我有一個dll,它有32位和64位兩種版本。我的.NET WinForm配置爲「任何CPU」,我的老闆不會讓我們針對不同的操作系統版本進行單獨安裝。所以我想知道:如果我在安裝時打包了兩個dll,那麼是否有辦法讓WinForm確定其64位/ 32位並加載正確的dll。基於64bit或32bit操作系統導入外部dll
我發現this article用於確定版本。但我不知道如何注入適當的 方式來定義我希望使用的方法的DLLImport屬性。有任何想法嗎?
我有一個dll,它有32位和64位兩種版本。我的.NET WinForm配置爲「任何CPU」,我的老闆不會讓我們針對不同的操作系統版本進行單獨安裝。所以我想知道:如果我在安裝時打包了兩個dll,那麼是否有辦法讓WinForm確定其64位/ 32位並加載正確的dll。基於64bit或32bit操作系統導入外部dll
我發現this article用於確定版本。但我不知道如何注入適當的 方式來定義我希望使用的方法的DLLImport屬性。有任何想法嗎?
你可以導入它們並決定通過.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);
你應該把兩種不同的私有extern
方法,並作出檢查IntPtr.Size
並調用正確版本的內部方法。
我的解決方案是創建一個抽象類,具有加載和封裝我的32位DLL的具體版本,以及加載和封裝64位DLL的單獨實現。基類中的單個工廠方法可用於基於IntPtr.Size
實例化適當的實現。
這種方法的好處在於,其餘代碼與平臺完全隔離 - 它只是使用基類工廠方法構造對象,並使用它。在所討論的DLL中以統一的方式調用多個方法也很容易,並且所有的「本地」代碼都可以輕鬆地推送到私有實現中。
您可以利用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);
這是一個很酷的解決方案。 – Kieron 2010-04-07 16:43:20
...或者你可以使用Marshal.GetDelegateForFunctionPointer()
做dynamic P/Invoke。
...或致電LoadLibrary()
with a fully qualified path CLR嘗試爲您加載它之前。
這實際上是我的「去」解決方案,如果我找不到一個更乾淨的方法來做到這一點。 – 2010-04-07 15:56:51