¿Cómo descargo una DLL que se ha cargado usando DllImport
en C#?Descargar una DLL cargada con DllImport
Respuesta
La forma más confiable de descargar una DLL no administrada de un proceso que se cargó mediante una declaración de [DllImport] pinvoke es cargarla usted mismo, nuevamente, pinvoking LoadLibrary(). Eso le da un manejo confiable a la DLL y funciona correctamente incluso si el nombre del módulo de la DLL es ambiguo. No tiene ningún efecto en tiempo de ejecución, que no sea el cargador de Windows aumentar el número de referencia interna en la DLL de 1 a 2.
A continuación, puede PInvoke FreeLibrary() dos veces para disminuir la cuenta de referencia a 0, pasando el IntPtr que obtuvo de LoadLibrary(). Eso descarga la DLL, así como cualquier DLL dependiente que se cargó.
Mira que obtendrá el fracaso muy desagradable cuando intenta PInvoke cualquier función exportada de la DLL de nuevo, cualquier momento después de hacer esto. El marshaller pinvoke no sabe que la DLL ya no está presente y llamará a la función a la dirección que cree que todavía es válida. Que bombardea su programa con una excepción AccessViolation si tiene suerte. O ejecuta un código de código completamente aleatorio si no tiene tanta suerte y el espacio de direcciones anteriormente ocupado por el DLL se volvió a utilizar por otro archivo DLL. Todo puede pasar entonces, nada de eso es bueno.
Esto debería liberar un módulo cargado previamente cuando llamó a la función P/Invocar.
[DllImport("kernel32", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadModule(string moduleName)
{
foreach(ProcessModule mod in Process.GetCurrentProcess().Modules)
{
if(mod.ModuleName == moduleName)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Eso * normalmente * funciona. Pero los nombres de los módulos pueden ser ambiguos, podría liberar la DLL incorrecta. –
Hans tiene razón. Entonces quizás mejor usando Path.GetFileName (mod.FileName) en lugar de mod.ModuleName? – Peter
O agárrate al puntero que obtienes de LoadLibrary y compara BaseAddress con eso. – yoyo
Sobre la base de Peters recomendación Esto funciona para mí:
[DllImport("kernel32", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadImportedDll(string DllPath)
{
foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules)
{
if (mod.FileName == DllPath)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Desde que llegué a través de la información aquí, mientras yo estaba mirando a su alrededor para obtener información Calculo que contribuiré de vuelta lo que terminé haciendo para arreglar un problema con el Sixense SDK en OSX IN UNITY. Verá allí una implementación de cargar dinámicamente/descarga de una dylib en OSX:
Sólo en caso de si eres fan de la programación funcional, entonces usted puede utilizar LINQ para lograr lo que @ IllidanS4 ha sugerido:
[DllImport("kernel32", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadModule(string moduleName)
{
var loadedAssemblyModule =
Process.GetCurrentProcess().Modules.OfType<ProcessModule>()
.FirstOrDefault(x => x.ModuleName == moduleName);
if (loadedAssemblyModule != null)
FreeLibrary(loadedAssemblyModule.BaseAddress);
}
- 1. DllImport, ¿cómo verificar si la DLL está cargada?
- 2. DllImport user32 vs user32.dll
- 3. ¿Dónde DLLImport busca archivos DLL no administrados?
- 4. ¿Cómo descargar una clase ya cargada en Java?
- 5. Mostrando un formulario desde una DLL cargada dinámicamente
- 6. ¿Verifica si ya está cargada una biblioteca dll? (Java)
- 7. C#/C++ en la misma solución - DllImport no encuentra DLL
- 8. Genera declaraciones C# DLLImport desde un dll nativo
- 9. dllimport procedimiento
- 10. dllimport no pudo encontrar dll aunque está en la RUTA
- 11. El atributo DllImport siempre carga la DLL no administrada
- 12. ¿Qué es [DllImport ("QCall")]?
- 13. Asp.Net C# DllImport problema
- 14. DllImport y char *
- 15. ¿Cómo puedo descargar una DLL usando ctypes en Python?
- 16. Establezca el atributo DllImport dinámicamente
- 17. Uso correcto de DllImport
- 18. DllImport vs Declare en VB.NET
- 19. Rastreo no funciona en una DLL .NET cargada desde EXE VB6
- 20. __declspec (dllimport/dllexport) y la herencia
- 21. función booleana C# DllImport con C++ no volver correctamente
- 22. Depuración de una DLL dinámicamente cargada de otro AppDomain en Runtime
- 23. DllImport no puede encontrar dll a pesar de que dll está en la misma carpeta que el ejecutable
- 24. Windows y C++: extern & __declspec (dllimport)
- 25. Una advertencia con DLL de 64 bits edificio
- 26. Cómo descargar la biblioteca (DLL) de Java JVM
- 27. DllNotFoundException con DllImport en Mono en Mac: arquitectura incorrecta
- 28. ¿Cómo uso DLLImport con structs como parámetros en C#?
- 29. ¿Cómo cargar y descargar dinámicamente un archivo DLL nativo?
- 30. ¿Dónde puedo descargar el Castle Windsor WcfIntegration Facilities dll?
Si tiene la intención de hacerlo solo para guardar unos pocos KB de memoria de un módulo cargado, entonces no vale la pena. CLR lo hace por sí solo siempre que se descargue appDomain. Me gustaría saber si tiene algún motivo real para intentar descargar el dll nativo. – RBT