![](/img/trans.png)
[英]InvalidCastException when using webbrowser and threads in c#
[英]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.