2010-04-07 13 views
8

Tengo un dll que viene en ambas versiones, 32 bits y 64 bits. Mi .NET WinForm está configurado para "Cualquier CPU" y mi jefe no nos deja tener instalaciones separadas para las diferentes versiones del sistema operativo. Así que me pregunto: si empaco ambos dlls en la instalación, entonces ¿hay alguna manera de que el WinForm determine si es 64bit/32bit y cargue el dll apropiado?Importar archivos dll externos basados ​​en sistemas operativos de 64 bits o 32 bits

Encontré this article para determinar la versión. Pero no estoy seguro de cómo inyectar la forma correcta para definir el atributo DLLImport en los métodos que deseo utilizar. ¿Algunas ideas?

Respuesta

6

¿Puede importarlos a la vez y tomar la decisión sobre a cuál llamar a través de .NET?

Por ejemplo:

[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

Esa es en realidad mi solución "ir a" si no puedo encontrar una manera más limpia de hacerlo. –

3

Usted debe hacer dos diferentes métodos extern privadas, y crea un método interno que comprueba IntPtr.Size y llama a la versión correcta.

3

Mi solución es crear una única clase abstracta, con una versión concreta que carga y envuelve mi DLL de 32 bits, y una implementación separada que carga y ajusta la DLL de 64 bits. Se puede usar un único método de fábrica en la clase base para crear una instancia de la implementación adecuada basada en el IntPtr.Size.

Lo bueno de este enfoque es que el resto del código está completamente aislado de la plataforma; solo construye un objeto utilizando el método de fábrica de la clase base y funciona con él. También es muy fácil llamar a múltiples métodos dentro de las DLL en cuestión, de manera uniforme, y todo su código "nativo" puede ser fácilmente enviado a una implementación privada.

14

Puede aprovechar la función de la API SetDllDirectory, ya que altera la ruta de búsqueda de ensamblajes no administrados. Almacene sus archivos DLL de 32 bits en el subdirectorio x86 del directorio de instalación de la aplicación, los archivos DLL de 64 bits en el subdirectorio x64.

ejecuta este código en el inicio de aplicaciones antes de hacer cualquier 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

Esa es una solución genial. – Kieron

Cuestiones relacionadas