3

所以我使用以下代码将每个扩展文件属性转储到调试控制台...

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 并需要安装程序和我正在开发的应用程序?

非常感谢!

4

2 回答 2

4

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

为避免生成互操作程序集,您只需在 C# 代码中声明与外壳已实现的 P/Invoke 函数和 COM 接口匹配的适当类型。在您的情况下,您正在寻找的是IShellFolder2界面(与Folder对象基本相同)。

通常,要执行您的要求,您会:

  1. 调用SHGetDesktopFolder返回一个IShellFolder指向桌面文件夹的接口。
  2. 调用IShellFolder::ParseDisplayName您想要的文件夹,它会为您提供一个“指向标识符列表的指针”(一个 PIDL),代表该文件夹的内部外壳标识符。
  3. 将您的IShellFolder转换为IShellFolder2(使用as,像任何其他接口一样)。
  4. 调用IShellFolder2::GetDetailsOf(),传递来自步骤 2 的 PIDL 和您想要的列。

您需要翻译两个 COM 接口,以及一个结构和一个 P/Invoke 函数,并将 C# 代码放入您的项目中。您可以摆脱IntPtr很多这种情况(例如 PIDL),因为您只需要在 COM 方法之间传递它们。(MSDN 文章会告诉您,您有责任在完成后释放内存;CLR 的互操作代码将在几乎所有情况下为您处理这些事情。)

pinvoke.net 将在这里为您提供帮助,这一系列关于从 MSDN 文章中进行 COM 互操作翻译的精彩博文也将提供帮助。

于 2012-04-30T21:17:37.347 回答
4

根据我的经验,从托管代码中使用 shell API 的最有效方法是使用Windows API Code Pack。这包含了 shell API 的所有有用部分,并使其可以从托管代码中轻松访问。下载包含许多示例,可帮助您上路。

于 2012-05-02T00:29:52.260 回答