c# - 在 C# 中使用 IClassFactory 时出现 InvalidCastException

标签 c# .net com interop com-interop

我试图在 C# 项目中不注册的情况下实例化 ActiveX 控件。我正在做以下事情:

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 接口(interface)是aximp.exe/source 生成的接口(interface)。我想避免使用附属程序集,因为我不能让它们使用无注册的 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 私有(private)字段。该字段最初通过从 CreateInstance 调用 CoCreateInstance 获取值。然后我调用其他方法来修复其他连接(所有这些都是私有(private)的,所以再次反射)。如果该类未注册,则在构造函数中抛出异常(CoCreateInstance 失败),因此我在 finally block 中执行此操作。

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

最佳答案

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

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

关于c# - 在 C# 中使用 IClassFactory 时出现 InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9062910/

相关文章:

c# - 尝试应用良好的依赖注入(inject)实践时遇到的问题

c# - 如何连接两个 HtmlNodeCollection

c# - LINQ 到 XML : Ignoring of the case of attributes

c# - 尝试学习 MEF 时遇到困难

com - COM 内存泄漏的常见原因是什么?

c# - 如何使用管理员权限启动进程 c#

c# - 如何将 Linq 扩展方法重写为委托(delegate)?

c# - 系统.BadImageFormatException : 64bit MVC 2 project - with step by step instruction to reproduce the error

c++ - `IDispatch::GetTypeInfo()` 接口(interface)是怎么回事?

c++ - 如何确保无法重入访问我的主 STA COM 服务器 (C++)?