3

我在 VC++ 中创建了 ocx 如果它是静态加载的,它可以正常工作,但是当我从程序集中动态加载它时,它会给出异常。

    public Assembly assembly;

    public Form1()
    {
        InitializeComponent();            
       assembly = Assembly.LoadFile(Application.StartupPath + "\\abc.ocx");

    }

它给出了以下异常该模块应包含程序集清单。

(来自 HRESULT 的异常:0x80131018)

4

2 回答 2

5

您必须执行许多在使用工具箱时通常会自动执行的步骤。首先,您必须运行 Aximp.exe 实用程序来生成 .NET 互操作程序集。使用 Visual Studio 命令提示符运行该工具。您将获得两个程序集,axinterop.foo.dll 包含一个从 AxHost 派生的包装类,并允许您将控件放在窗体上。还有 interop.foo.dll,它是使控件实现的 COM 接口可从 .NET 程序调用的互操作程序集。

接下来,您必须确保这些 DLL 存在于构建目录中。最好的办法是将它们添加到您的项目中并将它们的复制到输出目录设置为“如果更新则复制”。

现在您可以在代码中使用 Assembly.Load("axinterop.foo.dll") 来动态加载互操作程序集。

接下来,您必须创建控件实例,使用 Assembly.CreateInstance() 并传递 AxHost 包装类的类型名称。如果您不知道它的名称可能是什么,这并不明显,然后使用 ildasm.exe 查看 axinterop.foo.dll 程序集。将返回的对象强制转换为 AxHost。

接下来,您必须将控件添加到表单的 Controls 集合中,使其可见且可用。在创建控件实例之前,您不能调用任何接口方法,直到您添加了控件并且表单的 Load 事件已触发,才会发生这种情况。

接下来你必须使用反射或动态关键字来获取对控件实现的接口的引用,以防你需要设置属性或调用方法。这很难正确,您需要先使用从工具箱添加的控件来编写该代码,这样您就不必太费力地猜测正确的名称。


这显然是非常痛苦的,而且很难做到正确。通过向您的项目添加一个直接使用 OCX 并通过接口公开其重要属性的类库来提高获得良好结果的几率。并在那个上使用 Assembly.Load() 。

于 2012-05-03T11:41:56.863 回答
1

Assembly.LoadFile 只能加载 .Net 程序集而不是本机 dll/exe/ocx 文件。

您可以通过解决方案资源管理器-> 引用添加对 ocx 文件的引用,然后创建 ocx 类的实例。

于 2012-05-03T10:35:35.987 回答