Ian*_*oyd 8 windows windows-shell ipreviewhandler
如何获取IPreviewHandler
特定文件扩展名的shell ?
Windows允许开发人员为其自定义文件类型创建预览处理程序:
选择项目时,将调用预览处理程序,以在视图的阅读窗格中显示文件内容的轻量级,丰富的只读预览.这是在不启动文件的关联应用程序的情况下完成的.
预览处理程序是托管应用程序.主机包括Windows Vista或Microsoft Outlook 2007中的Windows资源管理器.
我想利用现有的基础IPreviewHandler
设施来获取文件的缩略图.
问题是我的文件没有放在shell命名空间中(即它们不在硬盘上).他们坐在记忆中,通过一个可以访问IStream
.这意味着我无法使用传统IExtractImage
接口; 因为它不支持从Stream加载文件.
幸运的是,这就是现代IPreviewHandler
支持(推荐并且更喜欢)从a加载数据的原因Stream
,并建议不要从文件加载预览:
此方法优先于Initialize,因为它能够使用无法通过Win32路径访问的流,例如具有.zip文件扩展名的压缩文件的内容.
没有关于获得与特定扩展相关联的正确方法的文档IPreviewHandler
.但是,如果我采取怎样的方向注册一个IPreviewHandler
,并读取对方的合同:
HKEY_CLASSES_ROOT
.xyz
(Default) = xyzfile
HKEY_CLASSES_ROOT
xyzfile
shellex
{8895b1c6-b41f-4c1c-a562-0d564250836f} //IPreviewHandler subkey
(Default) = [clsid of the IPreviewHandler]
Run Code Online (Sandbox Code Playgroud)
鉴于我知道扩展,我应该能够遵循相同的路线.让我们用一个真实世界的例子,一个.jpg
文件:
请注意,该文件有预览.请注意,我添加了第二个屏幕截图,以强调预览不是来自硬盘上的文件.
首先是它是一个.jpg
文件:
HKEY_CLASSES_ROOT
.jpg
(Default) = ACDC_JPG
HKEY_CLASSES_ROOT
ACDC_JPG
ShellEx
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
ContextMenuHandlers
Run Code Online (Sandbox Code Playgroud)
等等,{8895b1c6-b41f-4c1c-a562-0d564250836f}
预览处理程序没有子项.这必然意味着我们无法获取.jpg
文件的缩略图.
还原荒谬
细心的读者会意识到我要问的实际问题是:
如何获取仅包含在流中的图像的预览?
虽然这是一个有用的问题,但我遇到的真正问题是,如何使用答案IPreviewHandler
也是一个有用的问题.
所以随时回答; 或两者!
@hvd 有正确的答案。
文件类型有一个ShellEx键和{guid}
子键。每个{guid}
键代表一个特定的InterfaceID。
有许多标准 shell 接口可以与文件类型相关联:
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
提取图像{953BB1EE-93B4-11d1-98A3-00C04FB687DA}
IExtractImage2{e357fccd-a995-4576-b01f-234630154e96}
IT缩略图提供者{8895b1c6-b41f-4c1c-a562-0d564250836f}
IPreviewHandler例如,如果我想查找与文件关联的IPreviewHandler的clsid,我会查看:.jpg
HKEY_CLASSES_ROOT/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
但这不是我能看的唯一地方。我也可以看看:
HKEY_CLASSES_ROOT/.jpg
(default) = jpgfile
HKEY_CLASSES_ROOT/jpgfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
但这不是我能看的唯一地方。我也可以看看:
HKEY_CLASSES_ROOT/SystemFileAssociations/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
但这不是我能看的唯一地方。我也可以看看:
HKEY_CLASSES_ROOT/SystemFileAssociations/jpegfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
但这不是我能看的唯一地方。如果我认为该文件是一个图像,我还可以查看:
HKEY_CLASSES_ROOT/SystemFileAssociations/image/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
我是如何找到这些地点的?我是否只遵循记录和支持的位置?不,我使用 Process Monitor 监视 Explorer,因为它正在寻找IThumbnailProvider。
所以现在我想自己为文件类型使用标准的 shell 接口。这意味着我必须抓取这些位置。但是为什么要以未记录、不受支持的方式抓取这些位置。为什么要招致那个东西高高在上的家伙的愤怒?使用AssocQueryString:
HKEY_CLASSES_ROOT/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
Run Code Online (Sandbox Code Playgroud)
因此获得clsid
的IPreviewHandler
对.xps
文件:
Guid clsid = GetShellClsidForFileType(".xps", IPreviewHandler);
Run Code Online (Sandbox Code Playgroud)
综上所述,我们现在可以回答这个问题了:
IPreviewHandler GetPreviewHandlerForFileType(String extension)
{
//Extension: the file type to return IPreviewHandler for (e.g. ".xps")
Guid previewHandlerClassID = GetShellClsidForFileType(extension, IPreviewHandler);
//Create the COM object
IUnknown unk = CreateComObject(previewHandlerClassID);
//Return the actual IPreviewHanler interface (not IUnknown)
return (IPreviewhandler)unk;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3562 次 |
最近记录: |