2010-04-07 7 views
8

Ich habe eine DLL, die in 32-Bit- und 64-Bit-Version kommt. Mein .NET WinForm ist für "Any CPU" konfiguriert und mein Chef lässt uns keine separaten Installationen für die verschiedenen Betriebssystemversionen zulassen. Also ich frage mich: wenn ich beide dlls in der installation verpacke, dann gibt es eine Möglichkeit das WinForm zu ermitteln ob es 64bit/32bit hat und die richtige dll lädt.Importieren Sie externe DLL basierend auf 64bit oder 32bit OS

Ich habe this article zur Bestimmung der Version gefunden. Aber ich bin nicht sicher, wie man die korrekte Weise einfügt, um das DLLImport Attribut auf den Methoden zu definieren, die ich verwenden möchte. Irgendwelche Ideen?

Antwort

6

Können Sie beide importieren und entscheiden, welche über .NET aufgerufen werden soll?

Zum Beispiel:

[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

Das ist eigentlich meine "go to" -Lösung, wenn ich keinen saubereren Weg finde, es zu tun. –

3

Sie zwei verschiedene private extern Methoden machen sollte, und ein internes Verfahren machen, die IntPtr.Size und ruft die richtige Version überprüft.

3

Meine Lösung besteht darin, eine einzelne abstrakte Klasse zu erstellen, mit einer konkreten Version, die meine 32-Bit-DLL lädt und umhüllt und eine separate Implementierung, die die 64-Bit-DLL lädt und umschließt. Eine einzelne Factory-Methode in der Basisklasse kann verwendet werden, um die entsprechende Implementierung basierend auf IntPtr.Size zu instanziieren.

Das Schöne an diesem Ansatz ist, dass der Rest Ihres Codes vollständig von der Plattform isoliert ist - er erstellt nur ein Objekt mit Ihrer Basisklassen-Factory-Methode und arbeitet damit. Es ist auch sehr einfach, mehrere Methoden innerhalb der fraglichen DLLs auf eine einheitliche Art und Weise aufzurufen, und der gesamte "native" Code kann leicht in eine private Implementierung übertragen werden.

14

Sie können die API-Funktion SetDllDirectory nutzen, sie ändert den Suchpfad für nicht verwaltete Assemblys. Speichern Sie Ihre 32-Bit-DLLs im Unterverzeichnis x86 des Anwendungsinstallationsverzeichnisses, den 64-Bit-DLLs im Unterverzeichnis x64.

Führen Sie diesen Code bei app Start bevor Sie jede 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

Das ist eine coole Lösung. – Kieron

Verwandte Themen