【问题标题】:InvalidCastException when using IClassFactory in C#在 C# 中使用 IClassFactory 时出现 InvalidCastException
【发布时间】:2012-01-30 11:10:19
【问题描述】:

我正在尝试实例化一个 ActiveX 控件,而无需在 C# 项目中注册。我正在执行以下操作:

Guid guid = new Guid("(guid of my control here)");

var classFactory = ComHelper.GetClassFactoryFromDll("mycontrol.ocx", guid);
if (classFactory != null)
{
    object obj;
    classFactory.CreateInstance(null, ref guid, out obj); // getting the exception here
    if (obj != null) ocx = (obj as IMyControl);
}

ComHelper 代码主要基于this 文章,并且似乎与 IFilter 示例配合良好。

这是我的 IClassFactory 互操作代码:

    [ComVisible(false)]
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")]
    public interface IClassFactory
    {
        void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid,
                            [MarshalAs(UnmanagedType.Interface)] out object ppunk);

        void LockServer(bool fLock);
    }

IMyControl 接口是aximp.exe /source 生成的接口。我想避免使用附属程序集,因为我不能让它们使用无注册 COM 并且我们的部署需要这样做。什么引发异常?我正在使用与传统卫星组装方式相同的 guid。 guid 编组不正确吗?我怎样才能让它发挥作用?


为了完整起见:我设法做到了这一点。我的方法是查看 AxHost 源代码(使用 ILSpy),看看它在创建实例时做了什么:

private object GetOcxCreate()
{
    if (this.instance == null)
    {
        this.CreateInstance();
        this.RealizeStyles();
        this.AttachInterfaces();
        this.oleSite.OnOcxCreate();
    }
    return this.instance;
}

然后我创建了一个生成的 AxMyControl 类的实例,并通过反射替换了 instance 私有字段。该字段最初通过从CreateInstance 调用CoCreateInstance 来获取值。然后我调用了其他方法来修复其他连接(它们都是私有的,所以还是反射)。如果该类未注册,则在构造函数中抛出异常(CoCreateInstance 失败),因此我在 finally 块中执行此操作。

到目前为止,它似乎工作正常。

【问题讨论】:

    标签: c# .net com interop com-interop


    【解决方案1】:

    您在这里弄错了 Guid。 CreateInstance 调用要求您传递接口 IID,而不是 coclass CLSID。请改用 typeof(IMyControl).GUID。

    下一个可能的大故障模式是线程的单元状态,最好是 STA 或 COM 正在寻找可能不存在的代理。您正在绕过 CLR 的安全防护,在需要时编组接口指针。 永远不要使用来自错误线程的对象。不太确定这是否值得冒险。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-31
      • 2017-11-01
      • 2016-09-27
      • 2013-05-15
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多