2010-04-07 70 views
8

我有一個dll,它有32位和64位兩種版本。我的.NET WinForm配置爲「任何CPU」,我的老闆不會讓我們針對不同的操作系統版本進行單獨安裝。所以我想知道:如果我在安裝時打包了兩個dll,那麼是否有辦法讓WinForm確定其64位/ 32位並加載正確的dll。基於64bit或32bit操作系統導入外部dll

我發現this article用於確定版本。但我不知道如何注入適當的 方式來定義我希望使用的方法的DLLImport屬性。有任何想法嗎?

回答

6

你可以導入它們並決定通過.NET調用哪一個?

例如:

[DllImport("32bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")] 
public static extern int CallMe32 (IntPtr hWnd, String text, String caption, uint type); 

[DllImport("64bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")] 
public static extern int CallMe64 (IntPtr hWnd, String text, String caption, uint type); 
+1

這實際上是我的「去」解決方案,如果我找不到一個更乾淨的方法來做到這一點。 – 2010-04-07 15:56:51

3

你應該把兩種不同的私有extern方法,並作出檢查IntPtr.Size並調用正確版本的內部方法。

3

我的解決方案是創建一個抽象類,具有加載和封裝我的32位DLL的具體版本,以及加載和封裝64位DLL的單獨實現。基類中的單個工廠方法可用於基於IntPtr.Size實例化適當的實現。

這種方法的好處在於,其餘代碼與平臺完全隔離 - 它只是使用基類工廠方法構造對象,並使用它。在所討論的DLL中以統一的方式調用多個方法也很容易,並且所有的「本地」代碼都可以輕鬆地推送到私有實現中。

14

您可以利用SetDllDirectory API函數,它會改變非託管程序集的搜索路徑。將您的32位DLL存儲在應用程序安裝目錄的x86子目錄中,即64位子目錄中的64位DLL。

運行這段代碼在應用程序啓動你之前任何的P/Invoke:

using System.IO; 
using System.Reflection; 
using System.Runtime.InteropServices; 
... 

    public static void SetUnmanagedDllDirectory() { 
     string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); 
     path = Path.Combine(path, IntPtr.Size == 8 ? "x64 " : "x86"); 
     if (!SetDllDirectory(path)) throw new System.ComponentModel.Win32Exception(); 
    } 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern bool SetDllDirectory(string path); 
+0

這是一個很酷的解決方案。 – Kieron 2010-04-07 16:43:20