c#: how to know the full path of dll used in DllImport?
I've import dll in my code like that:
[DllImport("dll.dll", Char开发者_JAVA技巧Set = CharSet.Ansi)]
private static extern int function(String pars, StringBuilder err);
I was wondered that function works, but it is not inside project and not inside Debug or Release folders. I.e. "dll.dll" should not be availabe because it is not in the current project folder, however it IS available. Now I want to know the exact full path of the dll used at runtime, but don't know how to get it.
You're going to have to use the win32 API.
First use GetModuleHandle passing "dll.dll" to it. Then pass that handle to 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
);
See Dynamic-Link Library Search Order -- this should hold true with P/Invoke, but the behavior is slightly alterable depending upon load method. However it doesn't say how to determine the filename of a loaded DLL ;-)
A completely un-tested and perhaps ill-advised solution to find the DLL path at run-time. This assumes that P/Invoke and LoadLibrary use the same resolution (e.g. P/Invoke doesn't use LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH) and that there are no awful conflicts with this approach.
Load the DLL with LoadLibrary or LoadLibaryEx.
Find the filename of the module using GetModuleFileName and the handle obtained in step #1.
Unload the module with FreeLibrary. P/Invoke should keep the module reference-count > 0, but again, this is untested ;-)
(There is no guarantee about the correctness or validity of the above solution. Suggestions, warnings and/or corrections welcome. YMMV.)
Happy coding.
If you really want to find out, use dependency-walker
It can even 'monitor' your application in runtime and detect dynamic loads so nothing remains hidden
精彩评论