2010-11-03 114 views
2

比方說,我有一個典型的非託管的呼叫我想在一些DLL進行:搜索DLL時,DllImport是否遵守SafeDllSearchMode?

[DllImport("unmanaged.dll")] 
static extern int SomeFuncion1(int parm); 

是否DllImportAttribute尋求根據在註冊表中設置SafeDllSearchMode的DLL?我無法在MSDN中找到任何指示搜索順序是否確實遵循「標準搜索順序」的內容。

+1

btw from msdn - > *您可以提供完整或相對路徑。如果您沒有提供路徑,則DLL必須在運行時位於當前路徑中,除非通過其他方式加載DLL。但是請注意,如果移動了DLL,使用完全限定的路徑可能會導致不準確。* - http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.value(VS。 90)的.aspx。 – Ahmad 2010-12-13 07:15:22

回答

2

是的,P/Invoke編組只是使用LoadLibrary()。其中觀察設置。在SO文章中它實際上是做不到的,直到你親自嘗試,我確信沒有其他合理的選擇。 LoadLibrary完全屬於'硬'API函數的類別。

Fwiw,它會從來沒有找到與您的[DllImport]聲明的DLL。非託管DLL只有一個路徑,它們沒有像版本,文化,pkt這樣的託管裝配屬性。如果這實際上是一個具有這些屬性的託管程序集,那麼您可以使用Assembly.Load()加載它。但是你很難調用一個靜態函數,CLR不支持,每個方法都必須屬於一個類。

使用該DLL上的Dumpbin.exe/exports來找出實際上從該DLL導出的內容。

+0

我自己嘗試過(不能再等了),並且正在發佈答案的過程:)謝謝! – 2010-11-03 21:42:19

+1

這個* always *在你說「我會編輯它」之前編輯帖子*時效果更好。注意跨度在這裏很短。 – 2010-11-03 21:55:10

1

好吧,我很不耐煩,自己回答了這個問題,但漢斯在此期間回答了這個問題。

首先,我創建了一個測試工具:

[DllImport("SomeDllThatDoesntExist.dll")] 
public static extern void Test(); 

static void Main() 
{ 
    string currentWorkingDirectory = Directory.GetCurrentDirectory(); 
    Console.WriteLine(currentWorkingDirectory); 
    Directory.SetCurrentDirectory("E:\\foobar"); 
    currentWorkingDirectory = Directory.GetCurrentDirectory(); 
    Console.WriteLine(currentWorkingDirectory); 
    // Call method in DLL we know doesn't exist. 
    Test(); 
} 

然後,我Procmon對其進行監控,搜索路徑順序在Test()電話是:

  1. 執行目錄
  2. System32目錄
  3. 系統目錄(16位)
  4. Windows目錄
  5. 當前目錄( 「E:\ foobar的」)
  6. 我所有的$ PATH目錄

這表明它遵守了 「安全」 的搜索順序,因爲當前目錄是#5,而不是#2 ,因爲如果SafeDllSearchMode被禁用了。然後我添加HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode註冊表值並將其設置爲1(禁用),然後再次運行我的測試工具。搜索路徑實際上是相同的。我不知道我是否搞砸了添加註冊表項,但是真的,我想知道的唯一重要的事情是,如果默認情況下它遵循「安全」搜索順序路徑 - 這意味着當前目錄不是「 t#2的順序。