【发布时间】: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