Tengo dos versiones de System.Data.SQLite.DLL - para plataformas x86 y x64. La versión x86 se mantiene en la carpeta de la aplicación y la versión x64 se mantiene en la carpeta appFolder \ x64. La aplicación compilada como AnyCPU. ¿Cómo puedo cargar la versión necesaria de SQLite según la plataforma de Windows?Cargando ensamble x86 o x64
Respuesta
Si está usando SQLite desde http://system.data.sqlite.org, el System.Data.SQLite.DLL está completamente administrado. Existe una DLL nativa subyacente, SQLite.Interop.DLL, que debe cambiar según el proceso (32 o 64 bits).
Implemento las bibliotecas nativas en ". \ Native \ X64" para 64 bits y ". \ Native \ X86" para 32 bits. En el tiempo de ejecución P/Invoque SetDllDirectory para configurar el directorio de carga DLL apuntando a la ruta correcta para el proceso. http://msdn.microsoft.com/en-us/library/ms686203(v=vs.85).aspx
(Nótese que no estoy familiarizado con la arquitectura de la versión del legado System.Data.SQLite.DLL de http://sqlite.phxsoftware.com)
private static class NativeMethods
{
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool SetDllDirectory(string pathName);
}
...
// Underlying SQLite libraries are native.
// Manually set the DLL load path depending on the process.
var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Native");
if(IntPtr.Size == 8) // or: if(Environment.Is64BitProcess) // .NET 4.0
{
path = Path.Combine(path, "X64");
}
else
{
// X32
path = Path.Combine(path, "X86");
}
NativeMethods.SetDllDirectory(path);
Puede usar Environment.Is64BitProcess para identificar el proceso como de 64 bits. (Intentaría evitar detectar excepciones como control de flujo siempre que sea posible.)
Es una buena propuesta, pero no resuelve mi problema. – Rover
@Rover: ¿Cómo es eso? ¿Definitivamente tienes instalado .NET de 64 bits? –
Uso .NET 3.5 que no tiene esta variable. Creo que puedo verificar la versión de la plataforma, pero solo se evitan algunas excepciones, pero el ensamblaje necesario no está cargado. – Rover
¿No podría simplemente usar el origen de SQLite como un proyecto separado en su solución en lugar de un ensamblado precompilado? Con AnyCPU, el sistema se encargará de todo y no tiene que hacerlo en código ...
Es uno de los dlls que uso dividido en x86 y x64. No tengo el código fuente de todos los dlls usados. – Rover
Esto no resolverá ningún problema, ya que la arquitectura de la máquina de desarrollo no es siempre la misma que la máquina de despliegue. Cualquier CPU solo funciona para ensamblados .NET, no para archivos DLL nativos (uso de bruja SQLite bajo el capó) – BigBoss
Me sorprende que esto funcione en absoluto. Primero debería encontrar la versión x86 y fallar. Un enlace ensamblado fallido no produce otro intento a través de AssemblyResolve.
Claramente, el CLR no puede encontrar la versión x86 o fallará en el modo x64 también. En otras palabras, cuando arregle el problema, romperá el código de 64 bits. Primero busque el problema x86, use Fuslogvw.exe para ver qué carpetas se están sondeando para el ensamblaje.
Una solución real debería incluir mover el ensamblaje x86 a una carpeta diferente y ajustar el controlador de eventos en consecuencia. Puede probar IntPtr.Size para averiguar si se está ejecutando en modo de 64 bits (Tamaño == 8). También asegúrese de generar un nombre de ruta completo, utilizando la ruta relativa como lo hace ahora puede causar un error cuando el directorio de trabajo de la aplicación no está configurado donde usted espera que sea. Assembly.GetEntryAssembly(). Location te muestra la ruta del EXE.
- instalación DLL apropiada en el GAC (por ejemplo, versión de 64 bits en una plataforma de 64 bits)
- utilice el encuadernado ensamblado en su configuración web/aplicación (posiblemente en configuración de máquina)
- Califique completamente cualquier referencia de ensamblaje parcial en la configuración de su web/aplicación.
Hay soporte incorporado para esto en 1.0.80.0 y posterior.
Si las máquinas de desarrollo y de cliente pueden tener arquitecturas de procesador diferentes, es posible que se requiera más de un paquete binario. Para esta situación, se recomienda usar la característica de precarga de la biblioteca nativa. Está disponible desde la versión 1.0.80.0 y está habilitado de forma predeterminada.(from download page)
Sin embargo, para conseguir que funcione en mi propio plug-in también tuve que añadir este antes de hacer referencia SQLite por primera vez:
// Make SQLite work... (loading dll from e.g. x64/SQLite.Interop.dll)
System.Environment.SetEnvironmentVariable("PreLoadSQLite_BaseDirectory", System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
Sql.Data.SQLite...
Ver esta pregunta: New SQLite mixed assemblies
Algunos prog antivir previenen que SetDllDirectory() me haya llevado mucho tiempo darme cuenta de eso. Estamos utilizando
System.Reflection.Assembly myass = System.Reflection.Assembly.GetExecutingAssembly();
FileInfo fi = new FileInfo(myass.Location);
System.IntPtr moduleHandle = LoadLibraryEx(fi.Directory.FullName + "\\x64\\SQLite.Interop.DLL", IntPtr.Zero, 0);
para cargar la DLL de 64 bits con la ruta explícita. Se carga en ese punto y .NET Runtime utilizará la DLL en memoria en lugar de buscarla en el disco.
Upvote para 'myass' :) –
No funcionó en mi caso. Aunque he verificado con el depurador, la biblioteca nativa se carga correctamente. SQLite todavía arroja una excepción sobre la falta de DLL nativo. – BartoszKP
- 1. Escribiendo ensamble x86 en un procesador x64 bit
- 2. Visual Studio cargando el dll derecho (x86 o x64)!
- 3. Compilación para x86 y x64
- 4. ¿Puedo instalar Windbg x86/x64 en mi x64 WIN7?
- 5. Ejecutar MSI x86 o x64 desde MSBuild bootstrapper
- 6. ¿Los chips x86/x64 todavía usan microprogramación?
- 7. x86 Servicio de depurador remoto en x64
- 8. Acceso COM x86 desde x64 .NET
- 9. Operador Mod (%) en x86 vs x64
- 10. Usando x64 dll en la aplicación x86
- 11. PresentationCore y WindowsBase dlls en ambos entornos x64 y x86
- 12. TypeLoadException en x64, pero está bien en x86 con structlayouts
- 13. ¿Cómo puedo hacer que mi instalador VS2008 x86 instale ensamblajes x64 en x64?
- 14. Depuración aplicación .NET x86 en Windows x64 en VS2008
- 15. Diferencias de TVarData entre x86 y x64 Delphi
- 16. ¿Puede una aplicación x64 usar ensamblajes x86, y viceversa?
- 17. Entity Framework gira mucho más lento en x64 vs x86
- 18. WiX: registrar el componente .NET COM x86 x64
- 19. ¿Puedo ejecutar Visual Studio 2008 x86 en Windows Vista x64?
- 20. Configuración orientada tanto a x86 como a x64?
- 21. ¿En qué se diferencia la arquitectura x64 de x86
- 22. ¿Cuál es la diferencia entre x86 y x64
- 23. Configurar ASP.NET para usar x86 en x64 Windows
- 24. conmutación masiva entre x64 x86 en proyectos de instalación
- 25. StackOverflowException lanzada en sistemas x64; funciona correctamente en x86
- 26. ¿Compila ambos x86 y x64 en una configuración?
- 27. ¿Cómo puedo saber si estoy en x64 o x86 usando .NET?
- 28. ¿Qué paquete redistribuible de VC++ se debe elegir (x86 o x64)?
- 29. ¿Cómo determinar si se construyó un ensamblado .NET para x86 o x64?
- 30. Cómo saber si un ensamblado .NET se compiló como x86, x64 o cualquier CPU
He resuelto este problema. Gracias. Usé "IntPtr.Size == 8". Usé AppDomain.CurrentDomain.AssemblyResolve en lugar de SetDllDirectory. – Rover