繁体   English   中英

在C#中使用IClassFactory时出现InvalidCastException

[英]InvalidCastException when using IClassFactory in C#

我试图实例化一个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代码主要基于文章,似乎很好地工作的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生成的接口。 我想避免使用附属程序集,因为我不能使它们使用无reg的COM,我们的部署需要这样做。 抛出异常是什么? 我使用的是与传统的卫星组装方式相同的指南。 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块中执行此操作。

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

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

下一个可能的失败模式是线程的公寓状态,最好是STA或COM要寻找可能不存在的代理。 您正在绕过CLR所具有的安全防护装置,在需要时对接口指针进行编组。 切勿使用错误线程中的对象。 不太确定这是值得冒险的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM