2010-08-31 62 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; 
     } 
    } 
}