2011-04-02 15 views
5

he DLL importación en mi código de esa manera:C#: cómo saber la ruta completa de dll utilizada en DllImport?

[DllImport("dll.dll", CharSet = CharSet.Ansi)] 
    private static extern int function(String pars, StringBuilder err); 

me preguntaba esa función funciona, pero no es el proyecto en el interior y no en el interior de depuración o la liberación carpetas. Es decir. "dll.dll" no debería estar disponible porque no está en la carpeta del proyecto actual, sin embargo, está disponible. Ahora quiero saber la ruta completa exacta de la DLL utilizada en tiempo de ejecución, pero no sé cómo obtenerla.

+3

Esto puede ser útil: [biblioteca de vínculos dinámicos Orden de búsqueda] (http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx). Creo que lo mismo es cierto con P/Invoke. Sin embargo, no dice cómo determinar el nombre de archivo de un dll cargado ;-) –

+1

@pst: debe publicarlo como respuesta porque ... es la respuesta. –

Respuesta

7

Tendrás que usar la API win32.

Primero use GetModuleHandle pasando "dll.dll" a él. A continuación, pase ese identificador al GetModuleFileName.

string GetDllPath() 
{ 
     const int MAX_PATH = 260; 
     StringBuilder builder = new StringBuilder(MAX_PATH); 
     IntPtr hModule = GetModuleHandle("dll.dll"); // might return IntPtr.Zero until 
                // you call a method in 
                // dll.dll causing it to be 
                // loaded by LoadLibrary 

     Debug.Assert(hModule != IntPtr.Zero); 
     uint size = GetModuleFileName(hModule, builder, builder.Capacity); 
     Debug.Assert(size > 0); 
     return builder.ToString(); // might need to truncate nulls 
} 

    [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
    public static extern IntPtr GetModuleHandle(string lpModuleName); 

    [DllImport("kernel32.dll", SetLastError=true)] 
    [PreserveSig] 
    public static extern uint GetModuleFileName 
    (
     [In] IntPtr hModule,   
     [Out] StringBuilder lpFilename,   
     [In][MarshalAs(UnmanagedType.U4)] int nSize 
    ); 
1

Si realmente quiere saber, utilizar dependency-walker

Puede incluso 'vigilar' su aplicación en tiempo de ejecución y detectar cargas dinámicas por lo que nada permanece oculto

4

Ver Dynamic-Link Library Search Order - esto debe ser cierto con P/Invocar, pero el comportamiento es ligeramente alterable según el método de carga. Sin embargo, no dice cómo determinar el nombre de archivo de un archivo DLL cargado ;-)


Una solución completamente no-probado y tal vez poco recomendado para encontrar el camino de DLL en tiempo de ejecución. Esto supone que P/Invoke y LoadLibrary usan la misma resolución (por ejemplo, P/Invoke no usa LoadLibraryEx con LOAD_WITH_ALTERED_SEARCH_PATH) y que no hay conflictos terribles con este enfoque.

  1. carga la DLL con LoadLibrary o LoadLibaryEx.

  2. Busque el nombre de archivo del módulo utilizando GetModuleFileName y el identificador obtenido en el paso # 1.

  3. Descargue el módulo con FreeLibrary. P/Invoke debe mantener el módulo de referencia contador> 0, pero de nuevo, esto no se ha probado ;-)

(no hay ninguna garantía sobre la exactitud o validez de las anteriores soluciones. Las sugerencias, advertencias y/o las correcciones son bienvenidas. YMMV.)

Happy coding.

Cuestiones relacionadas