Discussion:
IThumbnailProvider and IStream object
(too old to reply)
philippe carret
2010-11-11 13:40:10 UTC
Permalink
Hi all happy Win32 developers ,

I'm trying to implement IThumbnailProvider with difficulties.
One of the main problem is IThumbnailProvider is working with IStream
and no more with file path

MS document says :
The object that implements this interface must also implement one of
the following interfaces.:

IInitializeWithStream. works
IInitializeWithItem (not working)
IInitializeWithFile (not working)

But because of specific needs, I need the full path to retrieve the
thumbnail of the file not an IStream
MS document says :
IStream "stat" contains pwcsName but it's not the full path just
filename

Any help ?
I could probably recreate a temp file to read the bitmap but sometime
file are 100 MB !
It would cost a lot of time just for thumbnails ...

Répondre Répondre à l'auteur Transférer
Leo Davidson
2010-11-12 10:20:23 UTC
Permalink
Post by philippe carret
The object that implements this interface must also implement one of
IInitializeWithStream. works
IInitializeWithItem (not working)
IInitializeWithFile (not working)
But because of specific needs, I need the full path to retrieve the
thumbnail of the file not an IStream
If the underlying components only understand filepaths and the files
are too large to write to temp then implementing IInitializeWithStream
probably doesn't make sense.

The IInitializeWithStream interface is recommended -- since it works
in more situations -- but only actually required when the shell has no
other choice. For example, if you're inside a zip file or some other
kind of virtual folder it can't pass you a filepath but it can pass
you an IStream. The shell will fall back on the other two interfaces
if a thumbnail provider is missing the stream one and the file really
exists on disk.

I checked my own 32/64-bit Thumbridge code ( http://www.pretentiousname.com/adobe_pdf_x64_fix/
) and it only implements IInitializeWithFile and IInitializeWithItem
(since the underlying Adobe PDF component doesn't understand IStream
and it didn't seem worth extracting PDFs to temp to get thumbnails
within zips). So it definitely should work.

Here is the relevant code from my IThumbnailHandler so you can compare
it against what you are doing:

http://www.pretentiousname.com/adobe_pdf_x64_fix/IThumb_without_stream.zip

It uses ATL but if you're not familiar with ATL don't worry; all ATL
is really doing is implementing QueryInterface. Just concentrate on
the two Initialize methods and the GetThumbnail method.

Saying that, if you're not seeing your Initalize methods called at all
the problem could be in your QueryInterface... Feel free to post the
code somewhere and I'll take a look.

(FWIW, my IInitializeWithFile::Initialize method turns the file path
into an IShellItem so that the GetThumbnail method can deal with
IShellItem whether it came via that or direct from
IInitializeWithItem::Initialize. You could do it the other way around
and always work on file paths. I forget why I did it that way around;
probably to do with what the underlying component expected.)
philippe carret
2010-11-20 10:22:18 UTC
Permalink
Thanks to
http://www.codemonkeycodes.com/2010/01/11/ithumbnailprovider-re-visited/
work
and SDK sample
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\winui\shell
\appshellintegration\RecipeThumbnailProvider
and
Leo davidson help http://www.pretentiousname.com/
and
MDSN blogs
and
many hours for what should be a simple task

For those who are looking inside IThumbnailProvider "magic" , here
are some advices :

1) With Windows Seven
x64 : dll compilation must be targeted to x64.
Win32 : dll must be targeted to win32

Be awax64 dll can't call win32 dll.
In that particular case, you must use a bridge 64/32 bits. Google-it
sample code with keywords ATL COM EXE 64 32
article here : http://www.dnjonline.com/article.aspx?id=jun07_access3264

2) Viisual Studio Config :

You must add To default VisualStudio (case for 2008) all x64 tools,
otherwise noway to set x64 in Project configuration
If you need SDK 7.0 or VisualStudio SP1 be careful to install SDK on
default location "C:\Program Files\Microsoft SDKs\Windows\v7.0" (not
on D:\")

Running "C:\Program Files\Microsoft SDKs\Windows\v7.0\Setup
\WindowsSdkVer.exe -version:v7.0" will fail for non-english people
- Set langage to english (usa) | run command line above | set langage
to yours
Check "path" to environnment Variable
Check Visual studio include, lib Path
After these step compilation will be OK with all v7.0 path

3) IInitializeWithItem and IInitializeWithFile will be called only
if :
DisableProcessIsolation DWORD32 (not DWORD64) = 1


Excerpt of code
#define szCLSID_SampleThumbnailProvider L"{AAAF0019-79AB-4e7f-9500-
AA3B5227DFE6}" // YOUR GUID
DEFINE_GUID(CLSID_SampleThumbnailProvider, 0xAAAf0019, 0x79ab, 0x4e7f,
0x95, 0x0, 0xaa, 0x3b, 0x52, 0x27, 0xdf, 0xe6); // YOUR GUID

REGKEY_SUBKEY_AND_VALUE keys[] = {
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider, NULL, REG_SZ, (DWORD_PTR)L"ABC
Thumbnail Provider"},
{HKEY_CLASSES_ROOT, L"CLSID\
\DisablePvvrocessIsolation", NULL, REG_DWORD, (DWORD) 1},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32", NULL, REG_SZ,
(DWORD_PTR)szModule},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32",
L"ThreadingModel", REG_SZ, (DWORD_PTR)L"Apartment"},
{HKEY_CLASSES_ROOT, L".abc\\shellex\\{E357FCCD-A995-4576-
B01F-234630154E96}", NULL, REG_SZ,
(DWORD_PTR)szCLSID_SampleThumbnailProvider}
};
return CreateRegistryKeys(keys, ARRAYSIZE(keys));
4) Refreshing Explorer
When testing (debugging) create one test file : "foo.abc"
In File explorer :
Hold CTRL Key and Drag and Drop the test file in same dir (foo.abc in
our case).
It will fire ThumbnailProvider and avoid cache to display old image
Otherwise you won't understand because nothing will happen

5) look in registry the key above to check everything is correctly
setup
philippe carret
2010-11-20 10:31:16 UTC
Permalink
Thanks to
http://www.codemonkeycodes.com/2010/01/11/ithumbnailprovider-re-visited/
work
and SDK sample
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\winui\shell
\appshellintegration\RecipeThumbnailProvider
and
Leo davidson help http://www.pretentiousname.com/
and
MDSN blogs
and
many hours for what should be a simple task

For those who are looking inside IThumbnailProvider "magic" , here
are some advices :

1) With Windows Seven
x64 : dll compilation must be targeted to x64.
Win32 : dll must be targeted to win32

2) If you musr call some Win32 code (ex: your existing dlls)
Be aware that for Windows File Explorer security reason DllHost.exe is
used
DllHost.exe will call your x64 dll and in that particular case it
can't call win32 dll.
You must use a bridge 64/32 bits.
Google-it to find sample code with keywords ATL COM EXE 64 32
article here : http://www.dnjonline.com/article.aspx?id=jun07_access3264

Solution is x64 dll will Call ATL EXE server 32 bits (Thanks to Leo)

3) Visual Studio Config :

You must add To default VisualStudio (case for 2008) all x64 tools,
otherwise noway to set x64 in Project configuration
If you need SDK 7.0 or VisualStudio SP1 be careful to install SDK on
default location "C:\Program Files\Microsoft SDKs\Windows\v7.0" (not
on D:\")

Running "C:\Program Files\Microsoft SDKs\Windows\v7.0\Setup
\WindowsSdkVer.exe -version:v7.0" will fail for non-English people
- Set language to English (usa) | run command line above | set
language
to yours
Check "path" to environment Variable
Check Visual studio include, lib Path
After these step compilation will be OK with all v7.0 path

4) IInitializeWithItem and IInitializeWithFile will be called only
if :
DisableProcessIsolation DWORD32 (not DWORD64) = 1

Excerpt of code
#define szCLSID_SampleThumbnailProvider L"{AAAF0019-79AB-4e7f-9500-
AA3B5227DFE6}" // YOUR GUID
DEFINE_GUID(CLSID_SampleThumbnailProvider, 0xAAAf0019, 0x79ab, 0x4e7f,
0x95, 0x0, 0xaa, 0x3b, 0x52, 0x27, 0xdf, 0xe6); // YOUR GUID

REGKEY_SUBKEY_AND_VALUE keys[] = {
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider, NULL, REG_SZ, (DWORD_PTR)L"ABC
Thumbnail Provider"},
{HKEY_CLASSES_ROOT, L"CLSID\
\DisablePvvrocessIsolation", NULL, REG_DWORD, (DWORD) 1},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32", NULL, REG_SZ,
(DWORD_PTR)szModule},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32",
L"ThreadingModel", REG_SZ, (DWORD_PTR)L"Apartment"},
{HKEY_CLASSES_ROOT, L".abc\
\shellex\\{E357FCCD-A995-4576-
B01F-234630154E96}", NULL, REG_SZ,
(DWORD_PTR)szCLSID_SampleThumbnailProvider}
};
return CreateRegistryKeys(keys, ARRAYSIZE(keys));


5) Refreshing Explorer
When testing (debugging) create one test file : "foo.abc"
In File explorer :
Hold CTRL Key and Drag and Drop the test file in same dir (foo.abc in
our case).
It will fire ThumbnailProvider and avoid cache to display old image
Otherwise you won't understand because nothing will happen

6) look in registry the key above to check everything is correctly
setup


Take coffee, patience, share your experience.
philippe carret
2010-11-20 10:44:00 UTC
Permalink
Thanks to
http://www.codemonkeycodes.com/2010/01/11/ithumbnailprovider-re-visited/
work
and SDK sample
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\winui\shell
\appshellintegration\RecipeThumbnailProvider
and
Leo davidson help http://www.pretentiousname.com/
and
dnjonline
and
MDSN blogs
and
many hours for what should be a simple task

For those who are looking inside IThumbnailProvider "magic" , here
are some advices (only for advanced users) :

1) With Windows Seven
x64 : dll compilation must be targeted to x64.
Win32 : dll must be targeted to win32

2) If you must call some Win32 code (ex: your existing dlls)
Be aware that for Windows File Explorer security reason DllHost.exe is
used
DllHost.exe will call your x64 dll and in that particular case it
can't call win32 dll.

You must use a 64/32 bits bridge .
Google-it to find sample code with keywords : ATL COM EXE 64 32
article here : http://www.dnjonline.com/article.aspx?id=jun07_access3264

Solution is : x64 dll will call ATL EXE server 32 bits (Thanks to Leo)

3) Visual Studio Config :

You must add To default VisualStudio (case for 2008) all x64 tools,
otherwise noway to set x64 in Project configuration
If you need SDK 7.0 or VisualStudio SP1 be careful to install SDK on
default location "C:\Program Files\Microsoft SDKs\Windows\v7.0" (not
on D:\")

Running "C:\Program Files\Microsoft SDKs\Windows\v7.0\Setup
\WindowsSdkVer.exe -version:v7.0" as explained in MDSN blogs will fail
for non-English people
- Set language to English (usa) | run command line above | set
language to yours

Check "Path" environment Variable and clean eventually any bad path
For ex. remove any v6.1 SDK path if necessary.
Check Visual studio General Properties | Directories : include, lib
Path
After these steps, compilation will be OK with all v7.0 path

4) IInitializeWithItem and IInitializeWithFile will be called only if
registry key :

DisableProcessIsolation is DWORD32 (not a DWORD64) = 1

Excerpt of code
#define szCLSID_SampleThumbnailProvider L"{AAAF0019-79AB-4e7f-9500-
AA3B5227DFE6}" // YOUR GUID
DEFINE_GUID(CLSID_SampleThumbnailProvider, 0xAAAf0019, 0x79ab, 0x4e7f,
0x95, 0x0, 0xaa, 0x3b, 0x52, 0x27, 0xdf, 0xe6); // YOUR GUID

REGKEY_SUBKEY_AND_VALUE keys[] = {
{HKEY_CLASSES_ROOT, L"CLSID\
\"szCLSID_SampleThumbnailProvider, NULL, REG_SZ,
(DWORD_PTR)L"ABCThumbnail Provider"},
{HKEY_CLASSES_ROOT, L"CLSID\
\DisablePvvrocessIsolation", NULL, REG_DWORD, (DWORD) 1},
{HKEY_CLASSES_ROOT, L"CLSID\
\"szCLSID_SampleThumbnailProvider L"\\InprocServer32", NULL, REG_SZ,
(DWORD_PTR)szModule},
{HKEY_CLASSES_ROOT, L"CLSID\
\"szCLSID_SampleThumbnailProvider L"\
\InprocServer32",L"ThreadingModel", REG_SZ,
(DWORD_PTR)L"Apartment"},
{HKEY_CLASSES_ROOT, L".abc\\shellex\\
{E357FCCD-A995-4576-B01F-234630154E96}", NULL, REG_SZ,
(DWORD_PTR)szCLSID_SampleThumbnailProvider}
};
return CreateRegistryKeys(keys, ARRAYSIZE(keys));

5) Refreshing Explorer

When testing (debugging) create one test file : "foo.abc"
In File explorer :
Hold CTRL Key and Drag and Drop the test file in same dir (foo.abc in
our case).
It will fire ThumbnailProvider and avoid cache to display old image
Otherwise you won't understand because nothing will happen

6) look in registry the key above to check everything is correctly
setup

Take coffee, patience, share your experience.
philippe carret
2010-11-23 11:09:53 UTC
Permalink
If you want to use MFC and ATL exe, you will have another problem.
A workaround exists and works perfectly well (thanks to Matt)
http://www.insidercoding.com/post/2009/02/27/Adding-MFC-to-an-ATL-EXE-Project.aspx

but code from MS is not OK :
http://support.microsoft.com/kb/173974

7) an error in code above : correc code is :

REGKEY_SUBKEY_AND_VALUE keys[] = {
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider, NULL, REG_SZ, (DWORD_PTR)L"My
Thumbnail Provider"},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider, L"DisableProcessIsolation",
REG_DWORD, (DWORD) 1},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32", NULL, REG_SZ,
(DWORD_PTR)szModule},
{HKEY_CLASSES_ROOT, L"CLSID\\"
szCLSID_SampleThumbnailProvider L"\\InprocServer32",
L"ThreadingModel", REG_SZ, (DWORD_PTR)L"Apartment"},
{HKEY_CLASSES_ROOT, L".abc\
\shellex", L"Trick only here to create shellex when not
existing",REG_DWORD, 1},
{HKEY_CLASSES_ROOT, L".abc\\shellex\\{E357FCCD-A995-4576-
B01F-234630154E96}", NULL, REG_SZ,
(DWORD_PTR)szCLSID_SampleThumbnailProvider}
};
8) other tricks for debugging :

when compiling the dll, dll will be locked by system and wont be
writable
what I did is open a "cmd" window and task manager.
Between compilation kill "explorer.exe" in windows task manager then
execute "explorer.exe" in "cmd" window

IN MS SDK 7.0 sample in main cpp method STDAPI::DllRegisterServer()
it's written :

....................
////
// This tells the shell to invalidate the thumbnail cache. This
is important because any .recipe files
// viewed before registering this handler would otherwise show
cached blank thumbnails.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

9) Windows 7 : Go to file explorer and seek option like "display
always icons and never thumbnail". must be Uncheked

10) look some of these links (some of them may be broken when you will
read this)
http://blogs.msdn.com/b/windowssdk/archive/2009/07/07/new-win32-samples-in-windows-sdk-for-windows-7-systems-management.aspx
http://msdn.microsoft.com/en-us/library/cc144114%28VS.85%29.aspx
http://code.msdn.microsoft.com/shellapplication
http://geekswithblogs.net/Jialiang/archive/2010/11/08.aspx
http://blogs.msdn.com/b/codefx/archive/2010/09/14/writing-windows-shell-extension-with-net-framework-4-c-vb-net-part-1.aspx


11) end : pray Windows 8 won't change the way Thumbnail works !!!
tindude
2012-07-06 06:41:56 UTC
Permalink
philippe carret wrote on 11/23/2010 06:09 ET
Post by philippe carret
If you want to use MFC and ATL exe, you will have another problem
A workaround exists and works perfectly well (thanks to Matt
http://www.insidercoding.com/post/2009/02/27/Adding-MFC-to-an-ATL-EXE-Project.asp
Post by philippe carret
but code from MS is not OK
http://support.microsoft.com/kb/17397
7) an error in code above : correc code is
REGKEY_SUBKEY_AND_VALUE keys[] =
{HKEY_CLASSES_ROOT, L"CLSID
szCLSID_SampleThumbnailProvider, NULL, REG_SZ, (DWORD_PTR)L"M
Thumbnail Provider"}
{HKEY_CLASSES_ROOT, L"CLSID
szCLSID_SampleThumbnailProvider, L"DisableProcessIsolation"
REG_DWORD, (DWORD) 1}
{HKEY_CLASSES_ROOT, L"CLSID
szCLSID_SampleThumbnailProvider L"InprocServer32", NULL, REG_SZ
(DWORD_PTR)szModule}
{HKEY_CLASSES_ROOT, L"CLSID
szCLSID_SampleThumbnailProvider L"InprocServer32"
L"ThreadingModel", REG_SZ, (DWORD_PTR)L"Apartment"}
{HKEY_CLASSES_ROOT, L".ab
shellex", L"Trick only here to create shellex when no
existing",REG_DWORD, 1}
{HKEY_CLASSES_ROOT, L".abcshellex{E357FCCD-A995-4576
B01F-234630154E96}", NULL, REG_SZ
(DWORD_PTR)szCLSID_SampleThumbnailProvider
}
8) other tricks for debugging
when compiling the dll, dll will be locked by system and wont b
writabl
what I did is open a "cmd" window and task manager
Between compilation kill "explorer.exe" in windows task manager the
execute "explorer.exe" in "cmd" windo
IN MS SDK 7.0 sample in main cpp method STDAPI::DllRegisterServer(
it's written
///
// This tells the shell to invalidate the thumbnail cache. Thi
is important because any .recipe file
// viewed before registering this handler would otherwise sho
cached blank thumbnails
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL)
9) Windows 7 : Go to file explorer and seek option like "displa
always icons and never thumbnail". must be Uncheke
10) look some of these links (some of them may be broken when you wil
read this
http://blogs.msdn.com/b/windowssdk/archive/2009/07/07/new-win32-samples-in-windows-sdk-for-windows-7-systems-management.asp
Post by philippe carret
http://msdn.microsoft.com/en-us/library/cc144114%28VS.85%29.asp
http://code.msdn.microsoft.com/shellapplicatio
http://geekswithblogs.net/Jialiang/archive/2010/11/08.asp
http://blogs.msdn.com/b/codefx/archive/2010/09/14/writing-windows-shell-extension-with-net-framework-4-c-vb-net-part-1.asp
Post by philippe carret
11) end : pray Windows 8 won't change the way Thumbnail works !!
I have tried the same as you mentioned in Point .7 i.e DisableProcessIsolatio
for adding into the registry but some how it still doesnt invoke initialize(
function in IInitializeWithFile interface
I am using Windows & 64Bit OS

Am I missing something here

Thanks

Loading...