filewinapirustthumbnailswindows-shell

Can't get thumbnail from IShellItem using IThumbnailProvider


So I've written some code to get the thumbnail from a file using a file path string as an input. First I get the IShellItem at the location, then get the IThumbnailProvider, and now I'm trying to get the thumbnail from the ThumbnailProvider.

unsafe {
    CoInitialize(None).expect("Failed to initialize COM");

    let item: IShellItem = SHCreateItemFromParsingName(
        w!("J:\\Apps\\Dolphin-x64\\Dolphin.exe"),
        None
    ).expect("Failed to get shell item");

    let thumb_provider: IThumbnailProvider = item
        .BindToHandler(None, &BHID_ThumbnailHandler)
        .expect("Failed to get thumbnail provider");

    let mut icon_bitmap_ref = MaybeUninit::<HBITMAP>::uninit();

    let mut alpha_type = MaybeUninit::<WTS_ALPHATYPE>::uninit();

    let mut icon_bitmap = MaybeUninit::<BITMAP>::uninit();

    thumb_provider
        .GetThumbnail(96, icon_bitmap_ref.as_mut_ptr(), alpha_type.as_mut_ptr())
        .expect("Failed to get thumbnail");
    // Errors right after this

    match
        GetObjectW(
            icon_bitmap_ref.assume_init(),
            std::mem::size_of::<BITMAP>() as i32,
            Some(icon_bitmap.as_mut_ptr().cast())
        )
    {
        0 => panic!("Failed to get bitmap"),
        _ => {
            let icon_image = match alpha_type.assume_init() {
                WTSAT_UNKNOWN => bitmap_to_image(icon_bitmap.assume_init(), true),
                WTSAT_RGB => bitmap_to_image(icon_bitmap.assume_init(), false),
                WTSAT_ARGB => bitmap_to_image(icon_bitmap.assume_init(), true),
                _ => unreachable!("Unknown alpha type"),
            };

            icon_image.save("icon.png").expect("Failed to save icon");
        }
    }

    CoUninitialize();
}

But every time I try and run it, it returns this error

Failed to get thumbnail provider: Error { code: HRESULT(0x80004001), message: "Not implemented" }

I honestly wouldn't be surprised if it's just a memory issue, since I've never programmed in C or C++, and I'm very new to win32 and low level rust, but the error message isn't helpful whatsoever, and I can't tell what I'm doing wrong.


Solution

  • As @RemyLebeau said, there is no thumbnail provider for the executable file.

    While the IShellItemImageFactory interface

    Exposes a method to return either icons or thumbnails for Shell items. If no thumbnail or icon is available for the requested item, a per-class icon may be provided from the Shell.

    A full example Using Image Factory.