Finding preview handler GUIDs for image types (gif, bmp, jpg, etc)

1.8k views Asked by At

If you use windows explorer and click on an item like a .docx or a .jpg file you get a preview of the item you clicked on within the explorer like this. I'm trying to replicate this within my windows form application and it works fine for .docx and .xlsx files but it doesn't for image file types. To my understanding preview handlers are registered under the GUID {8895b1c6-b41f-4c1c-a562-0d564250836f} in filextension/ShellEx. Using regedit you can see that .docx files have these .docx previewhandler GUID, but when you look at something like .jpg there is nothing to be found. (i.stack.imgur.com/40v6h.png). (I'm not allowed to post more than 2 links)

According to the first answer to this post (stackoverflow.com/questions/39373357/how-to-get-the-icon-path-and-index-associated-with-a-file-type) there are other locations the preview handler might be stored in for a .jpg, but they all show up empty for me.

My question: How do I get the preview handlers for the extension types windows can find but I can't. I think there are preview handlers stored somewhere but I don't know where they are or how to reach them.

This is the code I use to get the GUIDs of files. Succesfull for type .docx and .xlsx but not for image types. I go past every location mentioned in the last link but they all turn up null.

    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;
    }

This is my first post here so I hope I was informative enough. If there are things missing I'll add them when I get a chance. Thank you.

2

There are 2 answers

0
Jason Ching On

That's under local machine:

HKEY_LOCAL_MACHINE\Software\Classes\giffile\shellex{8895b1c6-b41f-4c1c-a562-0d564250836f}

I got this by decompiling PreviewConfig http://www.winhelponline.com/blog/previewconfig-tool-registers-file-types-for-the-preview-pane-in-windows-vista/

0
Ian Boyd On

Rather than crawl the registry yourself, you should use the AssocQueryString function.

You tell it .jpg, and what shell handler you're looking for:

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

and it will return you the clsid of that handler.

C#-style pseudo-code:

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());   
}

And so now if you want the IPreviewHandler for a file type:

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