c# - P/Invoke with Shell32,绕过 Interop.Shell32.dll 生成

标签 c# interop pinvoke dllimport shell32

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

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 资源,它必须生成一个 interop helper DLL。

有人知道 Shell32 中这些函数的 DLLImport 命令行来绕过整代互操作 DLL 吗?我检查了 pinvoke.net,在 Shell32 条目下,他们要么没有我要找的东西,要么没有按照我的期望命名。

如果无法使用 DLLImport 来完成此操作,有没有人知道使用托管 DLL 提取文件的所有扩展属性的方法,或者至少是我没有的方法生成一个帮助程序 DLL 并需要一个带有我正在开发的应用程序的安装程序?

非常感谢!

最佳答案

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

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

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

  1. 调用SHGetDesktopFolder返回 IShellFolder指向桌面文件夹的界面。
  2. 在您想要的文件夹上调用 IShellFolder::ParseDisplayName,这会为您提供一个“指向标识符列表”(PIDL)的指针,表示该文件夹的内部 shell 标识符。
  3. 将您的 IShellFolder 转换为 IShellFolder2(使用 as,就像任何其他接口(interface)一样)。
  4. 调用IShellFolder2::GetDetailsOf() ,传递第 2 步中的 PIDL 和您想要的列。

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

pinvoke.net 将在这里为您提供帮助,这本书写得非常好 series of blog posts关于从 MSDN 文章中进行 COM 互操作翻译。

关于c# - P/Invoke with Shell32,绕过 Interop.Shell32.dll 生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10390260/

相关文章:

c# - 通过事件参数的异步事件处理程序回调

c# - 最佳实践 : Pros and Cons for using AutoMapper or LINQ (LINQ to Objects) for mapping between a Domain Model and a Presentation Model

c# - PreviewMouseMove 触发两次

java - 如何在 Kotlin 中实现 Serializable 使其在 Java 中也能工作?

c++ - 使用 c++/cli 中的 std::string 参数调用 native c++ dll

c# - C DLL 处理从 C# 调用的 FILE * - 传入和传出流

c# - 找到包含特定子元素的父元素

c# - VB5 dll,如何从 C# ( .NET 4.5 ) 调用函数

c# - 如何从 Xamarin iOS 调用 sysctl?

c# - 我让 C DLL 从 C# 向 c DLL 发送参数