2010-08-31 61 views
5

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

我以为我应该能够通过它的文件路径引用dll,将特定版本保留为false,将interop类型嵌入到false中,并将其复制到false,然后使用该机器的任何版本,但我当我这样做时会得到一个错误 - “调用的目标引发了异常。”

有没有办法延迟绑定DLL,即使它是COM?

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

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

+0

通常你在编译时链接interop DLL,如果它存在于系统上,它会在运行时加载COM DLL。错误中是否还有其他信息或内部异常?是否有错误代码(0xZZZZZZZZ)?你能链接堆栈跟踪,还是提供了关于你的应用程序的太多信息? Peachtree API,它是COM还是链接到COM的DLL? – 2010-08-31 18:04:12

回答

7

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

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

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

查看this article了解更多详情。

+1

和.net 4.0,你可以使用新的'动态'类型,并有晚期方法调用绑定,消除了需要添加类型引用http://msdn.microsoft.com/en-us/library/dd264736.aspx – 2010-08-31 18:59:50

+0

我想补充的一件事是,当你从创建实例中获取对象时,可以将其转换为正确的接口类型,因此尽管创建是迟到的,但仍然具有静态绑定。 – zumalifeguard 2010-08-31 19:39:28

+0

感谢您的帮助。你的想法让我走上了正确的道路。 – Yoenhofen 2010-09-01 17:39:07

0

这是解决

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; 
     } 
    } 
}