Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract high resolution icon or thumbnail for file

I'm trying to get a high resolution icon or thumbnail in Windows given a full path to that file. Doesn't need to be a thumbnail — a good looking Icon will be great. I Don't care if it's an HICON or an HBITMAP: I'm going to put it in a GDI+ object and render it into a device context.

I've tried using SHGetFileInfo (with various variations on flags), but never get more than a ~32x32 icon back, which scales horribly to the 128 pixels or so that I need.

if (!SHGetFileInfoW(path, 0, &fi, sizeof(fi),
                    SHGFI_ICON | SHGFI_ICONLARGE | SHGFI_TYPENAME))
    return GetLastError();

// fi.hIcon is a valid icon here, but it's horrible quality with
// a black mask on it. I want higher quality, and dare I dream of
// alpha channel? Mask is acceptable, i suppose.

SHGetFileInfo returns "" when I call with SHGFI_ICONLOCATION (which appears to be a known problem with that API).

I've also tried using SHCreateItemFromParsingName name with the intention of getting IThumbnailProvider, but BindToHandler always returns E_NOTIMPL for BHID_ThumbnailHandler ...

IShellItem *psi;
hr = SHCreateItemFromParsingName(path, NULL, IID_PPV_ARGS(&psi));
if (SUCCEEDED(hr))
{
    IThumbnailProvider *pThumbProvider;
    hr = psi->BindToHandler(NULL, BHID_ThumbnailHandler,
                            IID_PPV_ARGS(&pThumbProvider));
    if (SUCCEEDED(hr))
    { 
    // never get here because hr == E_NOTIMPL !!!

I've actually run the Microsoft Thumbnail Providers Sample and found that it suffers from the same problem with BindToInterface.

So, any suggestions on what else I could try? I just want something picture-y that more or less represents this file at, say, at least 100px size — just anything better than 32x32 ...

like image 954
MarcWan Avatar asked Aug 07 '12 05:08

MarcWan


People also ask

How do I export an EXE icon?

Right-click the EXE file for the software you want to extract an icon from and select Properties. Click the Icons tab shown directly below. Select an icon to extract there. Choose a size and color option on the Device images menu.

How do I extract an icon from a shortcut?

Here's a quick way to do that: If you have access to a shortcut that points to the application, right-click it and select “Properties.” Then click “Open File Location” in the “Shortcut” tab, and you'll be taken directly to the EXE's location in File Explorer.


2 Answers

If you are targeting Vista and higher, you can get a 256x256 icon from the jumbo image list. If you need to target XP, you can at least use the extra large image list, which is 48x48 (slightly better than 32x32 large).

#include <commoncontrols.h>
#include <shellapi.h>

HICON GetHighResolutionIcon(LPTSTR pszPath)
{
    // Get the image list index of the icon
    SHFILEINFO sfi;
    if (!SHGetFileInfo(pszPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX)) return NULL;

    // Get the jumbo image list
    IImageList *piml;
    if (FAILED(SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&piml))) return NULL;

    // Extract an icon
    HICON hico;
    piml->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hico);

    // Clean up
    piml->Release();

    // Return the icon
    return hico;
}
like image 92
Raymond Chen Avatar answered Nov 07 '22 17:11

Raymond Chen


Have you tried ExtractIconEx()?

It has dedicated parameters to extract arrays of both small and large icons from executables, DLLs, or icon files. From there you can select the size best suited to your needs. The API call is available from Win2K onwards.

like image 28
U007D Avatar answered Nov 07 '22 16:11

U007D