I'm trying to get a thumbnail of a file in Windows API. I did find a way, but the code example requires Windows version 8 minimum, I would prefer a way that works in at least 7 or Vista, preferably in XP. If there is a platform independent way of obtaining the thumbnail I would prefer to do that, but I haven't been able to find one.
-
possible duplicate of [C# get thumbnail from file via windows api](http://stackoverflow.com/questions/1439719/c-sharp-get-thumbnail-from-file-via-windows-api) – SLaks Oct 22 '13 at 16:41
-
2No, this is not a duplicate, I'm asking a question about windows api, not .net api. Or are you telling me that I can use .net api from a normal windows client program, in that case explain how. – Dude Dawg Oct 22 '13 at 16:47
-
That .Net API is a wrapper around the underlying Windows API. – SLaks Oct 22 '13 at 16:47
-
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761848(v=vs.85).aspx http://www.vbforums.com/showthread.php?527704-2008-Using-Shell-s-IExtractImage-to-extract-file-thumbnail – SLaks Oct 22 '13 at 16:48
-
Do you happen to have a link to the methods that it exposes? – Dude Dawg Oct 22 '13 at 16:52
-
If you are not interested in .NET, then please remove the windows-api-code-pack tag, since the Windows API code pack is a .NET library. – Raymond Chen Oct 22 '13 at 23:08
2 Answers
There is no single API that works on all Windows versions, because Microsoft keeps changing the thumbnail APIs from one Windows version to another.
On Win2K up to and including Vista (not sure about later versions), you can retrieve an IShellFolder
for the file's parent folder using SHGetDesktopFolder()
and IShellFolder::ParseDisplayName()
(or SHParseDisplayName()
on XP and later), then use IShellFolder::GetUIObjectOf()
to retrieve the desired child file's IExtractImage
interface, and then call its GetLocation()
method to set the image size and its Extract()
method to retrieve the actual image.
On Vista and later, you can either:
1) use IThumbnailProvider
. Query it for one of its IInitializeWith...
interfaces (IInitializeWithStream
, IInitializeWithItem
, or IInitializeWithFile
) to tell it which file you are interested in, and then call its GetThumbnail()
method to get the actual image. Alternatively, you can get an IShellItem
for the desired file and then call its BindToHandler
method to obtain the file's IThumbnailProvider
.
2) use IThumbnailCache
. Pass an IShellItem
representing the desired file to its GetThumbnail()
method to get the image.
3) use IShellItemImageFactory
. Use one of the SHCreateItemFrom...()
functions (SHCreateItemFromIDList()
, SHCreateItemFromParsingName()
, SHCreateItemFromRelativeName()
, SHCreateItemInKnownFolder()
, SHCreateItemWithParent()
) to obtain this interface for a given file, then call its GetImage()
method.

- 555,201
- 31
- 458
- 770
Using powershell on a Win 7 system:
PS> $myimage = [System.Drawing.Image]::FromFile("c:\image.jpg");
PS> $mythumb = $myimage.GetThumbnailImage(72, 72, $null, [intptr]::Zero);
PS> $mythumb.Save("c:\thumb.jpg")

- 6,462
- 2
- 25
- 22
-
1This won't do since it gets the entire image, the point with a thumbnail cache is mostly performance. – Dude Dawg Oct 22 '13 at 17:15
-
@DudeDawg According to [this](http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx), it will get the thumbnail if it exists: _"If the Image contains an embedded thumbnail image, this method retrieves the embedded thumbnail and scales it to the requested size. If the Image does not contain an embedded thumbnail image, this method creates a thumbnail image by scaling the main image."_ – David Oct 22 '13 at 17:21
-
@David: That's for thumbnails which are _embedded_ in the `System.Drawing.Image` .Net class. Your random `image.jpg` probably does not contain one, and `FromFile` doesn't try the `IThumbnailCache`. – MSalters Apr 04 '22 at 16:04