使用Shell32进行P / Invoke,绕过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命令行来绕过整个生成的互操作DLL? 我检查了pinvoke.net,在Shell32条目下,他们要么没有我想要的东西,要么它没有被命名为我所期待的。

如果无法使用DLLImport来实现这一点,那么是否有人知道使用托管DLL提取有关文件的所有扩展属性的方法,或者至少有一种方法可以在我不需要生成帮助DLL并要​​求安装程序与我正在开发的应用程序?

谢谢你!

大多数Windows Shell APIfunction都具有返回COM接口的P / Invoke入口点,因此您很少需要显式创建ShellClass CoClass实例。 (您正在使用的对象, FolderFolderItem ,主要用于后期绑定客户端,如脚本语言;使用C#,您可以做得更好。)

为了避免必须生成互操作程序集,您只需要在C#代码中声明与shell已经实现的P / Invoke函数和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的互操作代码将在几乎所有情况下为您处理这些内容。)

pinvoke.net将帮助你在这里,以及关于从MSDN文章进行COM互操作翻译的这篇精彩的博客文章系列 。

根据我的经验,从托管代码使用shell API的最有效方法是使用Windows API代码包 。 这包含了shell API的所有有用部分,并使其可以从托管代码中轻松访问。 下载包含大量示例,可帮助您顺利完成任务。