Pregunta

Tengo un archivo DLL no administrado (el scilexer.dll de Scintilla editor de código, utilizado por Scintilla.Net de CodePlex ) que se carga desde una aplicación administrada Trough el componente Scintilla.Net. La aplicación se ejecuta Windows administrados sin problemas en ambos entornos de 32 y 64 bits, pero necesito para crear diferentes instalaciones que utiliza el 64 o el 32 scilexer.dll.

¿Hay una manera de distribuir los dos archivos DLL en el formato de 32 y 64 bits para que el cargador de DLL de .NET Framework carga el archivo DLL no administrado en el formato de 32 o 64 bits, dependiendo de alguna opción .config o algún "nombre mágico camino "cosas?

¿Fue útil?

Solución

P / Invoke utiliza LoadLibrary para cargar DLL, y si ya existe una biblioteca cargado con un nombre dado, LoadLibrary se devuelve. Así que si usted puede dar a las dos versiones de la DLL del mismo nombre, pero ponerlos en diferentes directorios, puede hacer algo como esto sólo una vez antes de la primera llamada a una función de scilexer.dll, sin necesidad de duplicar sus declaraciones extern:

    string platform = IntPtr.Size == 4 ? "x86" : "x64";
    string dll = installDir + @"\lib-" + platform + @"\scilexer.dll";
    if (LoadLibrary(dll) == IntPtr.Zero)
        throw new IOException("Unable to load " + dll + ".");

Otros consejos

Por desgracia, no sé nada acerca de esta DLL en particular. Sin embargo, cuando se hace la relación P / Invoke a sí mismo, y se puede hacer frente con un poco de duplicación, es posible crear un proxy para cada plataforma.

Por ejemplo, supongamos que usted tiene el siguiente interfaz, que debería implementarse ya sea por un DLL de 32 bits o de 64:

public interface ICodec {
    int Decode(IntPtr input, IntPtr output, long inputLength);
}

Para crear los proxies:

public class CodecX86 : ICodec {
    private const string dllFileName = @"Codec.x86.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

y

public class CodecX64 : ICodec {
    private const string dllFileName = @"Codec.x64.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

Y por último hacer una fábrica que recoge el más adecuado para usted:

public class CodecFactory {
    ICodec instance = null;

    public ICodec GetCodec() {
        if (instance == null) {
            if (IntPtr.Size == 4) {
                instance = new CodecX86();
            } else if (IntPtr.Size == 8) {
                instance = new CodecX64();
            } else {
                throw new NotSupportedException("Unknown platform");
            }
        }
        return instance;
    }
}

Como los archivos DLL se cargan con pereza la primera vez que se invocan, esto realmente funciona, a pesar de cada plataforma sólo ser capaz de cargar la versión que es nativa a la misma. Ver este artículo para una explicación más detallada.

El mejor que he ocurre es lo siguiente:

  • Distribuir mi solicitud con dos DLL nombrados 64 o 32
  • En el código de inicio principal son los siguientes:
    
    File.Delete(Application.StartupPath + @"\scilexer.dll");
    {
      // Check for 64 bit and copy the proper scilexer dll
        if (IntPtr.Size == 4)
        {
          File.Copy(Application.StartupPath + @"\scilexer32.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
        else
        {
          File.Copy(Application.StartupPath + @"\scilexer64.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
    }

Puede colocar el archivo DLL en system32. El 32 bits en syswow64 y el bit 64 en el system32 real. Para la aplicación de 32 bits, cuando parecían system32 acceso se les redirige a Syswow64.

Puede crear una entrada en el registro. La clave de software tiene una subclave denominada Wow6432Node que la aplicación de 32 bits ver como la clave de software.

Esto es lo que instalador powershell hace .

DLL no administrados se pueden instalar en el lado a lado con sus homólogos administrados GAC. Este artículo debe explicar cómo funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top