2012-04-30 71 views
3

所以我用下面的代碼來轉儲每一個擴展的文件屬性來調試控制檯...的P/Invoke與SHELL32,旁路Interop.Shell32.dll代

ShellClass shellClass = new ShellClass(); 
Folder dir = shellClass.NameSpace(Path.GetDirectoryName(sFilePath)); 
FolderItem item = dir.ParseName(Path.GetFileName(sFilePath)); 
for (int i = 0; i < 267; i++) 
{ 
    System.Debug.WriteLine(dir.GetDetailsOf(item, i)); 
} 

由於SHELL32是非我無法直接在程序中嵌入DLL資源,它必須生成一個互操作幫助程序DLL。

任何人都知道Shell32中的這些函數的DLLImport命令行來解決整個interop DLL的問題?我檢查了pinvoke.net和Shell32條目,他們要麼沒有我要找的東西,要麼沒有命名我期待的東西。

如果無法使用DLLImport來完成此任務,是否有人知道使用託管DLL來獲取有關文件的所有擴展屬性的方法,或者至少有一種方法可以在不使用託管DLL的情況下執行此操作必須生成一個幫助程序DLL並需要一個安裝程序和我正在開發的應用程序?

非常感謝!

+2

您是否知道.NET 4 +中的嵌入式互操作功能? http://msdn.microsoft.com/en-us/library/dd997297.aspx –

+0

不幸的是,我卡住了3.5,但這是一個很酷的功能,得到後來的書籤。 –

回答

4

大多數Windows Shell API功能都具有返回COM接口的P/Invoke入口點,因此您很少需要顯式創建ShellClass CoClass實例。 (您正在使用的對象,FolderFolderItem,大多是指供後期綁定客戶,如腳本語言;用C#你可以做的更好。)

爲了避免生成interop程序集,你只要需要在C#代碼中聲明與P/Invoke函數和shell已經實現的COM接口相匹配的適當類型。在你的情況下,你要找的是IShellFolder2接口(它基本上與Folder對象相同)。

通常情況下,做你的要求,你會:

  1. 呼叫SHGetDesktopFolder返回一個IShellFolder接口指向桌面文件夾。
  2. 請致電IShellFolder::ParseDisplayName關於您想要的文件夾,它爲您提供了一個「指向標識符列表」(PIDL)的指針,表示該文件夾的內部shell標識符。
  3. 將您的IShellFolder轉換爲IShellFolder2(使用as,與其他任何接口一樣)。
  4. 撥打IShellFolder2::GetDetailsOf(),傳遞步驟2中的PIDL和所需的列。

您需要翻譯兩個COM接口,再加上一個結構和一個P/Invoke函數,並將C#代碼放入項目中。你可以通過IntPtr得到很多(比如PIDL),因爲你只需要在COM方法之間傳遞它們。 (MSDN文章會告訴你,完成後你有責任釋放內存;在幾乎所有情況下,CLR的interop代碼都會爲你處理這些東西)。

pinvoke.net將幫助你在這裏,就像這篇精心編寫的series of blog posts關於從MSDN文章中做COM互操作轉換一樣。

+0

哎呀!我會繼續前進,並將其作爲答案,因爲這是一個合適的解決方案,但我正在考慮引入額外的1k +代碼行來實現所有這些工作要比將DLL安裝到安裝程序中的工作要多得多。 –

+0

C#的後期COM是錯誤的。真的,不要這樣做。額外的代碼已經存在。你只需要使用你最喜歡的搜索引擎來找到它。 –

+0

這不是太多的代碼;也許從p/invoke.net複製/粘貼一百行代碼給你的接口(儘管我不確定我喜歡IShellFolder如何翻譯,它肯定會工作)。實際得到這些屬性的代碼幾乎是從你所擁有的線到線的翻譯。給我一些時間,我會嘗試做一個工作樣本。 –

4

根據我的經驗,從託管代碼使用shell API的最有效方法是使用Windows API Code Pack。這封裝了shell API的所有有用部分,並使其可以從託管代碼輕鬆訪問。下載包括很多例子,以幫助你順利完成任務。