VB.net或Windows API:如何找出文件资源管理器使用的图标?

时间:2016-11-03 17:38:28

标签: vb.net winapi shell32.dll

我目前正在使用VB.net开发Windows桌面应用程序,我希望将文件和文件夹浏览界面直接集成,即用户无需打开文件浏览器对话框来选择文件。

我的文件浏览器应该与原始的Windows文件浏览器类似,至少在最常见的位置使用相同的图标。例如,我想在“收藏夹”文件夹中包含相应的图标(请注意,这不是IE收藏夹文件夹,但是当您在文件的地址栏中键入shell:links时出现的文件夹资源管理器)。

我的问题是获取图标。到目前为止,我已经为Windows API的某些功能编写了一个包装类,特别是SHGetKnownFolderPathSHGetFileInfo。我的方法如下:

1)使用SHGetKnownFolderPath获取相应位置的完整路径(这取决于Windows版本和本地化)。 此部分的工作方式与预期相同。例如,在我的系统(W7 Pro x64)上,SHGetKnownFolderPath在使用相应的rfid查询时返回“C:\ Users \ Administrator \ Links”。

2)使用SHGetFileInfo获取Windows认为是1)中获得的路径的默认图标的图标。此部分在技术上也可以正常工作,但返回了错误的图标 - 错误的是它是另一个图标,而不是Windows文件资源管理器用于同一位置。

我尝试了四个不同的位置(MyLibraries,MyFavorites(Links),MyComputer,MyNetwork)。 MyLibraries的图标是预期的图标,其他三个图标与Windows文件资源管理器使用的图标完全不同。

所以我有一些问题

1)有没有办法检测标准Windows文件资源管理器为某些文件夹使用哪些图标,例如“收藏夹”(我的机器上的C:\ Users \ Administrator \ Links)?我会对一般解决方案感兴趣(即适用于所有地点的解决方案described here)。

2)如果没有这种方式,我会找出shell32.dll中所有感兴趣的图标的数量(索引)(实际上,目前只有少数几个)。我可以确定这些索引将来不会改变吗?

3)根据this document,我必须在使用CoInitialize之前致电SHGetFileInfo。我相信.NET框架在启动之前会自动为主线程执行此操作,因此尚未自行完成(应用程序的开发刚刚开始,目前只有一个线程)。

我认为对CoInitialize的遗失调用不能成为“错误”图标的原因。如果我在这里错了,请告诉我。

潜在的解决方案可能是使用.NET语言或本机Windows API / SDK。只要有一些方法(即使是非常复杂的方法)在VB.net中使用解决方案,我会很高兴。

1 个答案:

答案 0 :(得分:3)

Explorer使用两种方法来检测任何对象,文件或文件夹的图标。

1)调用IShellFolder.GetUIObjectOf(IExtractIconA / W)并使用IExtractIcon。

2)查询IShellFolder.QueryInterface(IShellIcon)并调用IShellIcon.GetIconOf。

你也可以这样做。