我在我的代码中导入了dll:
[DllImport("dll.dll", CharSet = CharSet.Ansi)]
private static extern int function(String pars, StringBuilder err);
我想知道该函数是否有效,但它不在项目内部,也不在Debug或Release文件夹中。即“dll.dll”不应该是可用的,因为它不在当前项目文件夹中,但是它可用。现在我想知道运行时使用的dll的确切完整路径,但不知道如何获取它。
答案 0 :(得分:7)
您将不得不使用win32 API。
首先使用GetModuleHandle向其传递“dll.dll”。然后将该句柄传递给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 :(得分:4)
参见Dynamic-Link Library Search Order - 这应该适用于P / Invoke,但是根据加载方法,行为略有可变。但是它没有说明如何确定加载的DLL的文件名; - )
一个完全未经测试且可能不明智的解决方案在运行时找到DLL路径。这假设P / Invoke和LoadLibrary使用相同的分辨率(例如,P / Invoke不使用LoadLibraryEx和LOAD_WITH_ALTERED_SEARCH_PATH)并且与此方法没有可怕的冲突。
使用LoadLibrary或LoadLibaryEx加载DLL。
使用GetModuleFileName和步骤1中获得的句柄查找模块的文件名。
使用FreeLibrary卸载模块。 P / Invoke应保持模块引用计数> 0,但同样,这是未经测试的; - )
(无法保证上述解决方案的正确性或有效性。欢迎提出建议,警告和/或更正.YMMV。)
快乐的编码。
答案 2 :(得分:1)
如果您真的想知道,请使用dependency-walker
它甚至可以在运行时“监控”您的应用程序并检测动态负载,因此不会隐藏任何内容