c#:如何知道DllImport中使用的dll的完整路径?

时间:2011-04-02 22:28:37

标签: c#

我在我的代码中导入了dll:

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

我想知道该函数是否有效,但它不在项目内部,也不在Debug或Release文件夹中。即“dll.dll”不应该是可用的,因为它不在当前项目文件夹中,但是它可用。现在我想知道运行时使用的dll的确切完整路径,但不知道如何获取它。

3 个答案:

答案 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)并且与此方法没有可怕的冲突。

  1. 使用LoadLibraryLoadLibaryEx加载DLL。

  2. 使用GetModuleFileName和步骤1中获得的句柄查找模块的文件名。

  3. 使用FreeLibrary卸载模块。 P / Invoke应保持模块引用计数> 0,但同样,这是未经测试的; - )

  4. (无法保证上述解决方案的正确性或有效性。欢迎提出建议,警告和/或更正.YMMV。)

    快乐的编码。

答案 2 :(得分:1)

如果您真的想知道,请使用dependency-walker

它甚至可以在运行时“监控”您的应用程序并检测动态负载,因此不会隐藏任何内容