2015-01-14 57 views
2

我正在構建一個使用一些user32.dll函數和幾個gdi32.dll函數的PowerShell腳本。過去我不得不多次這樣做。爲什麼沒有預構建的PInvoke DLLs?

我厭倦了在我的PowerShell代碼中查看字符串中這些巨大的C#代碼塊。我也厭倦了爲每個我打算使用的函數尋找PInvoke代碼。我想有一個包裝所有(已知)user32.dll函數的單個DLL,以便我可以一勞永逸地將它們提供給我。

我已經google了一下,似乎無法找到任何預先建立的PInvoke包裝器DLL的所有已知函數在user32.dll,win32.dll,或其他流行的非託管dll。爲什麼是這樣?我明白,他們可能不會穩定,並會不斷需要更新 - 這是理由嗎?

我也注意到,http://pinvoke.net/提供了一個自動生成簽名的Visual Studio插件......這是否意味着有一個pinvoke.net Web服務,我可以使用它自動生成基於其數據庫最新狀態的dll ?

+0

這聽起來像是[SWIG](http://www.swig.org/)可以照顧的東西?但我知道我對Java的情況並不滿意,所以我想出了一個名爲[JavaCPP]的工具(https://github.com/bytedeco/javacpp)... –

+0

你可以自己寫這個。什麼東西阻止你?基於pinvoke.net的自動生成將是一個壞主意,因爲那裏的內容質量低。 –

+0

我剛剛找到了網絡服務:http://www.pinvoke.net/pinvokeservice.asmx,所以我想我會自己寫,然後在這裏發佈。 'function PInvoke($ module){...}' – Nacht

回答

0

在互聯網上沒有預建DLL的原因,以及爲什麼沒有人使用PInvoke.net的Web服務來自動化這個,是因爲大多數數據對於人類來說是理解和解釋的,但不是很好供自動化腳本消費。如果它被清理了一噸,但可能是可能的。

很多這些信息仍然存儲在msdn上,但創建包含所有已知函數的這種包裝器DLL需要時間。 AFAIK,還沒有人做到這一點。我很想花時間瀏覽user32.dll中的586個已知函數,並創建一個可供其他人使用的包裝DLL,但我沒有時間,就像大多數人會這樣做我想。我認爲微軟並沒有這樣做,只是因爲他們覺得這不值得他們的時間。

此外,似乎這些函數中的某些函數是以這樣一種方式構建的,甚至可能沒有正確的方式將其轉換爲託管代碼,並確定它們可以工作。特別是,解釋哪些C#類型應該用於C指針似乎是一個問題。

+0

還有很多東西可以通過'char *'...'string','StringBuilder','ref char'等來表示。這些事情使自動翻譯變得複雜。 – Joey

0

可以很容易地使用您提到的P/Invoke Web服務。我試了一下,發現P/Invoke數據庫並沒有完全形成,它可以通過腳本導入。這是而不是以定義的方式構建,所以你要麼想出一些「智能解析」或自己修復錯誤,這將是太多的工作! kernel32.dll已經產生了4000行代碼,更不用說其他數百個庫了。

這就是我迄今爲止所做的,並且將結果放入C#文件時,不能編譯。過濾出「TODO」項目是一回事,但是許多項目也包含語法錯誤,涉及未明確定義的其他結構等等。問題根本在於數據庫沒有任何形式的明確格式。這只是純文本字段用戶可以輸入文本。

使用下面的腳本的結果時,我得到127編譯錯誤。我認爲這是最接近你能得到的。

PInvokeServiceSoapClient client = new PInvokeServiceSoapClient(); 
client.Open(); 
foreach (FunctionInfo function in client.SearchFunction("kernel32.dll", new WikiVersion())) 
{ 
    Console.WriteLine(function.Function); 
    try 
    { 
     foreach (SignatureInfo signature in client.GetResultsForFunction(function.Function, function.Module)) 
     { 
      if (signature.Language == "C#") 
      { 
       if (!signature.Signature.Contains("TODO")) 
       { 
        if (!signature.Summary.StartsWith("TODO")) 
        { 
         Console.WriteLine("/// <summary>\r\n/// " + signature.Summary + "\r\n/// </summary>"); 
        } 
        Console.WriteLine(signature.Signature.Replace("|", "\r\n")); 
       } 
      } 
     } 
    } 
    catch { } 
} 
client.Close(); 

也許有一天你想出瞭如何創建一個包含所有WinAPI的功能,並作爲一切包裝DLL中的創意。它會很酷!

相關問題