查找图像类型(gif、bmp、jpg等)的预览处理程序GUID

3
如果您使用Windows资源管理器并单击像.docx或.jpg这样的项目,您将在资源管理器中预览所单击的项目,如此所示。我正在尝试在我的Windows表单应用程序中复制这个功能,对于.docx和.xlsx文件,它运行良好,但对于图像文件类型则不行。 据我了解,预览处理程序在GUID {8895b1c6-b41f-4c1c-a562-0d564250836f}下在filextension / ShellEx中注册。使用regedit可以看到.docx文件具有这些.docx预览程序GUID,但是当您查看像.jpg这样的内容时,无法找到任何内容。 (i.stack.imgur.com/40v6h.png)。(我不允许发布超过2个链接)
根据此帖子的第一个答案(stackoverflow.com/questions/39373357/how-to-get-the-icon-path-and-index-associated-with-a-file-type),.jpg可能存储在其他位置的预览处理程序,但对我来说,它们都为空。
我的问题:如何获取Windows可以找到但我无法找到的扩展名的预览处理程序。我认为预览处理程序存储在某个地方,但我不知道它们在哪里或如何访问它们。
这是我用来获取文件GUID的代码。对于.docx和.xlsx类型,成功了,但对于图像类型则不行。我经过上面提到的每个位置,但它们都为空。
    private Guid GetPreviewHandlerGUID(string filename)
    {
        // open the registry key corresponding to the file extension
        string extention = Path.GetExtension(filename);
        RegistryKey ext = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64);

        // open the key that indicates the GUID of the preview handler type
        string className = Convert.ToString(ext.GetValue(null));
        RegistryKey test = ext.OpenSubKey(className + "\\ShellEx\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
        if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
        // sometimes preview handlers are declared on key for the class
        if (className != null) {
                test = ext.OpenSubKey(extention + "\\ShellEx\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
            if (test == null)
                test = ext.OpenSubKey("SystemFileAssociations\\" + className + "\\ShellEx\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
            if (test == null)
                test = ext.OpenSubKey("SystemFileAssociations\\" + extention + "\\ShellEx\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
            if (test == null)
                test = ext.OpenSubKey("SystemFileAssociations\\image\\ShellEx\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
            if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
        }

        return Guid.Empty;
    }

这是我的第一篇帖子,希望我的信息已经足够详尽。如果有遗漏的地方,我会在有机会时添加。谢谢。
2个回答

0

0

不要自己爬取注册表,你应该使用AssocQueryString函数。

告诉它.jpg和你要查找的shell处理程序:

  • {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}: IExtractImage
  • {953BB1EE-93B4-11d1-98A3-00C04FB687DA}: IExtractImage2
  • {8895b1c6-b41f-4c1c-a562-0d564250836f}: IPreviewHandler
  • {e357fccd-a995-4576-b01f-234630154e96}: IThumbnailProvider

它会返回处理程序的clsid。

C#风格的伪代码

private Guid GetShellObjectClsid(String filename, Guid desiredHandler)
{
    String ext = Path.GetExtension(filename);
    String sInterfaceID = desiredHandler.ToString("B"); // B ==> The COM format {xxxx}

    uint bufferLen = 100; //more than enough to hold a 38 character clsid
    StringBuilder buffer = new StringBuilder(bufferLen);

    HRESULT hr = AssocQueryString(ASSOCF_INIT_DEFAULTTOSTAR, ASSOCSTR_SHELLEXTENSION, 
          ext, buffer, ref bufferLen);
    if (hr != S_OK)
    {
       //Marhsal.ThrowExceptionForHR(hr);
       return null;
    }

    String s = sb.ToString();

    return new Guid(sb.ToString());   
}

现在,如果您想要获取文件类型的 IPreviewHandler

Guid previewHandlerClsid = GetShellObjectClsid("a.jpg", IID_IPreviewHandler);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接