使用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实例。 (您正在使用的对象, Folder
和FolderItem
,主要用于后期绑定客户端,如脚本语言;使用C#,您可以做得更好。)
为了避免必须生成互操作程序集,您只需要在C#代码中声明与shell已经实现的P / Invoke函数和COM接口匹配的相应类型。 在您的情况下,您正在寻找的是IShellFolder2
接口(它与Folder
对象基本相同)。
通常,为了做你想要的,你会:
- 调用
SHGetDesktopFolder
返回指向桌面文件夹的IShellFolder
接口。 - 在您想要的文件夹上调用
IShellFolder::ParseDisplayName
,它为您提供了一个“指向标识符列表的指针”(PIDL),表示该文件夹的内部shell标识符。 - 将您的
IShellFolder
转换为IShellFolder2
(使用as
,就像任何其他接口一样)。 - 调用
IShellFolder2::GetDetailsOf()
,传递步骤2中的PIDL和所需的列。
您将需要翻译两个COM接口,加上一个结构和一个P / Invoke函数,并将C#代码放入项目中。 你可以通过IntPtr
来解决很多问题(比如PIDL),因为你只需要在COM方法之间传递它们。 (MSDN文章将告诉您,在完成后您将负责释放内存; CLR的互操作代码将在几乎所有情况下为您处理这些内容。)
pinvoke.net将帮助你在这里,以及关于从MSDN文章进行COM互操作翻译的这篇精彩的博客文章系列 。
根据我的经验,从托管代码使用shell API的最有效方法是使用Windows API代码包 。 这包含了shell API的所有有用部分,并使其可以从托管代码中轻松访问。 下载包含大量示例,可帮助您顺利完成任务。