【问题标题】:Load a COM dll at runtime?在运行时加载 COM dll?
【发布时间】:2010-08-31 17:59:57
【问题描述】:

我正在为 Peachtree API 编写一个应用程序,它需要使用任何版本的 API。不幸的是,Peachtree 2011 中的 dll 无法与 Peachtree 2010 交互,反之亦然,即使这两个 dll 存储在同一位置并使用完全相同的代码运行。

我认为我应该能够通过它的文件路径引用 dll,将特定版本保留为 false,将互操作类型设置为 false,并将本地复制为 false,它只会使用机器拥有的任何版本,但我明白了当我这样做时出现错误 - “调用的目标已引发异常。”

有没有办法后期绑定 dll,即使它是 COM?

我可以提供您认为有帮助的任何代码示例,但这更多的是项目设置问题。

编辑:非常感谢大家的帮助。我在另一个人的问题上找到了我的解决方案并将其发布在这里。

【问题讨论】:

  • 通常在编译时链接interop DLL,如果它存在于系统中,它将在运行时加载COM dll。错误中是否有更多信息或内部异常?是否有错误代码 (0xZZZZZZZZ)?您可以链接堆栈跟踪,还是提供有关您的应用程序的太多信息? Peachtree API,是 COM,还是链接到 COM 的 DLL?

标签: c# .net com-interop


【解决方案1】:

对 COM 对象的后期绑定要求您不要将 COM 库的引用添加到您的 .NET 项目中。相反,您应该使用这样的东西来创建 COM 对象:

   Type type = Type.GetTypeFromProgID("Excel.Application")
   object app = Activator.CreateInstance(type);

然后,它将在运行时绑定到任何版本的 COM 库。

更多详情请见this article

【讨论】:

  • 在 .net 4.0 中,您可以使用新的 dynamic 类型并具有后期方法调用绑定,无需添加类型引用 msdn.microsoft.com/en-us/library/dd264736.aspx
  • 我想补充一点的是,当你从创建实例中获取对象时,你可以将它转换为正确的接口类型,所以你仍然有静态绑定,即使创建是后期绑定。
  • 链接中的文章很棒!非常感谢!
【解决方案2】:

这就是解决办法

Compile a version agnostic DLL in .NET

如果该链接失效,关键是处理 AppDomain.CurrentDomain.AssemblyResolve 事件,如下所示。每当程序集绑定失败时都会触发该事件,因此您可以自己解决它,修复版本冲突。

using System.Reflection;

static Program()
{
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
    {
        AssemblyName requestedName = new AssemblyName(e.Name);

        if (requestedName.Name == "Office11Wrapper")
        {
            // Put code here to load whatever version of the assembly you actually have

            return Assembly.LoadFile("Office11Wrapper.DLL");
        }
        else
        {
            return null;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    相关资源
    最近更新 更多