如何获得文件扩展名的IPreviewHandler?
我如何获得特定文件扩展名的shell IPreviewHandler
?
背景
Windows允许开发人员为其自定义文件类型创建预览处理程序:
预览处理程序在选定项目时调用,以在视图的阅读窗格中显示文件内容的轻量级丰富只读预览。 这是在不启动文件的关联应用程序的情况下完成的。
预览处理程序是托管应用程序。 主机包括Windows Vista或Microsoft Outlook 2007中的Windows资源管理器。
我想利用现有的IPreviewHandler
设施获取文件的缩略图。
在流
问题是我的文件不在shell命名空间中(即它们没有坐在硬盘上)。 他们坐在记忆里,通过IStream
访问。 这意味着我不能使用传统的IExtractImage
接口; 因为它不支持从Stream加载文件。
幸运的是,这就是现代IPreviewHandler
支持(推荐并优先选择)从Stream
加载数据的原因,并建议不要从文件加载预览:
由于该方法能够使用不能通过Win32路径访问的流,例如具有.zip文件扩展名的压缩文件的内容,因此此方法优先于初始化。
那么,我如何得到它?
没有关于如何IPreviewHandler
与特定分机关联的IPreviewHandler
的正确方法的文档。 但是,如果我按照如何注册 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]
鉴于我知道延期,我应该能够遵循相同的路线。 让我们以一个真实世界的例子来说明一个.jpg
文件:
注意该文件有预览。 请注意,我仅包含第二张截图,以强化预览不是来自坐在硬盘上的文件的想法。
让我们开始拼写!
首先是它是一个.jpg
文件的事实:
HKEY_CLASSES_ROOT
.jpg
(Default) = ACDC_JPG
HKEY_CLASSES_ROOT
ACDC_JPG
ShellEx
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
ContextMenuHandlers
等等, {8895b1c6-b41f-4c1c-a562-0d564250836f}
没有{8895b1c6-b41f-4c1c-a562-0d564250836f}
子项。 这意味着我们无法获得.jpg
文件的缩略图。
减少荒谬
真正的问题
仔细的读者会意识到我所问的实际问题是:
如何获取仅包含在流中的图像的预览?
虽然这是一个有用的问题,而且我遇到的实际问题是,如何使用IPreviewHandler
也是一个有用的问题。
所以随时回答; 或两者!
奖金阅读
@ hvd有正确的答案。
文件类型具有带{guid}
子项的ShellEx密钥。 每个{guid}
键代表一个特定的InterfaceID 。
有许多可以与文件类型关联的标准shell接口:
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
IExtractImage {953BB1EE-93B4-11d1-98A3-00C04FB687DA}
IExtractImage2 {e357fccd-a995-4576-b01f-234630154e96}
IThumbnailProvider {8895b1c6-b41f-4c1c-a562-0d564250836f}
IPreviewHandler 例如,如果我想查找与.jpg
文件关联的IPreviewHandler的clsid ,我会查找:
HKEY_CLASSES_ROOT/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
但那不是我唯一能看的地方。 我也可以看看:
HKEY_CLASSES_ROOT/.jpg
(default) = jpgfile
HKEY_CLASSES_ROOT/jpgfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
但那不是我唯一能看的地方。 我也可以看看:
HKEY_CLASSES_ROOT/SystemFileAssociations/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
但那不是我唯一能看的地方。 我也可以看看:
HKEY_CLASSES_ROOT/SystemFileAssociations/jpegfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
但那不是我唯一能看的地方。 如果我认为该文件是一个图像,我也可以查看:
HKEY_CLASSES_ROOT/SystemFileAssociations/image/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
我是如何找到这些位置的? 我是否只遵循记录和支持的位置? 不,我使用Process Monitor监视Explorer,因为它正在寻找IThumbnailProvider 。
所以现在我想为我自己的文件类型使用标准的shell接口。 这意味着我必须抓取位置。 但为什么要以无证件,不支持的方式抓取这些地点。 为什么从[the thing] [2]的顶端引起[guy] [1]的愤怒? 使用[ AssocQueryString ] [3]:
Guid GetShellClsidForFileType(String fileExtension, Guid interfaceID)
{
//E.g.:
// String fileExtension = ".jpg"
// Guid interfaceID = "{8895b1c6-b41f-4c1c-a562-0d564250836f}"; //IExtractImage
//The interface we're after - in string form
String szInterfaceID := GuidToString(interfaceID);
//Buffer to receive the clsid string
DWORD bufferSize := 1024; //more than enough to hold a 38-character clsid
String buffer;
SetLength(buffer, bufferSize);
HRESULT hr := AssocQueryString(
ASSOCF_INIT_DEFAULTTOSTAR,
ASSOCSTR_SHELLEXTENSION, //for finding shell extensions
fileExtension, //e.g. ".txt"
szInterfaceID, //e.g. "{8895b1c6-b41f-4c1c-a562-0d564250836f}"
buffer, //will receive the clsid string
@bufferSize);
if (hr <> S_OK)
return Guid.Empty;
Guid clsid;
HRESULT hr = CLSIDFromString(buffer, out clsid);
if (hr <> NOERROR)
return Guid.Empty;
return clsid;
}
所以要获得IPreviewHandler
的.xps
文件的clsid
:
Guid clsid = GetShellClsidForFileType(".xps", IPreviewHandler);
链接地址: http://www.djcxy.com/p/20451.html
上一篇: How to get the IPreviewHandler for a file extension?
下一篇: Iptables forward port range to another port range on a different host