1

From what I understand windows Thumbnail providers are DLLs that implement the IThumbnailProvider interface. Yet, when viewing the exported functions of an existing Thumbnail provider I see:

  • DLLCanUnloadNow
  • DLLGetClassObject
  • DLLRegisterServer
  • DllUnregisterServer

Using these exported functions, how is is possible to get at the GetThumbnail function.

Alex K.
  • 171,639
  • 30
  • 264
  • 288
Jamie
  • 79
  • 6
  • 1
    No, those exports are just part of the plumbing for *COM*, which is what you need to use to invoke that method. – Alex K. Aug 13 '15 at 13:01
  • 1
    `DLLGetClassObject` is a factory function, it creates the objects that actually implement the functionality of the COM interface. – Jonathan Potter Aug 13 '15 at 13:11
  • So as a COM DLL, should I not be able to add a reference directly from VS. When doing so I get the message "A reference to my.dll could not be added. Make sure that the file is acessible, and that is is a valid assembly or COM component" – Jamie Aug 13 '15 at 13:39
  • When running the DLL through IlbImp.exe I get the message "The input file my.dll is not a valid type library." – Jamie Aug 13 '15 at 13:39
  • What language are you working with? – Alex K. Aug 13 '15 at 13:43
  • I am trying to use C#, but can be flexible if it is easier through C++. – Jamie Aug 13 '15 at 13:47
  • C# http://stackoverflow.com/questions/21751747/extract-thumbnail-for-any-file-in-windows – Alex K. Aug 13 '15 at 13:49
  • Thanks for the link, it does work great, though that approach is limited. The user requires a handler to be installed on there system, and there is no way to force a specific thumbnail provider to be used (if the user has another as there default). It is these limitations that make me want to call the Thumbnail Provider directly. – Jamie Aug 13 '15 at 14:24

1 Answers1

-1

Delphi sample but it easy to convert it to any language you use:

function LoadBitmapWithShellExtension(const ADllFileName: UnicodeString; const ACLSID: TCLSID;
  const AFileName: UnicodeString; ASize: Integer; out AAlpha: WTS_ALPHATYPE): HBITMAP;
type
  TDllGetClassObject = function(const CLSID, IID: TGUID; out Obj): HRESULT; stdcall;
var
  DllModule: HMODULE;
  DllGetClassObject: TDllGetClassObject;
  ClassFactory: IClassFactory;
  ThumbnailProvider: IThumbnailProvider;
  InitializeWithFile: IInitializeWithFile;
  PersistFile: IPersistFile;
begin
  DllModule := LoadLibraryW(PWideChar(ADllFileName));
  if DllModule = 0 then RaiseLastOSError;
  try
    @DllGetClassObject := GetProcAddress(DllModule, 'DllGetClassObject');
    if not Assigned(DllGetClassObject) then
      RaiseLastOSError;
    OleCheck(DllGetClassObject(ACLSID, IClassFactory, ClassFactory));
    try
      OleCheck(ClassFactory.CreateInstance(nil, IThumbnailProvider, ThumbnailProvider));
      try
        if Succeeded(ThumbnailProvider.QueryInterface(IInitializeWithFile, InitializeWithFile)) then
          try
            OleCheck(InitializeWithFile.Initialize(PWideChar(AFileName), STGM_READ));
          finally
            InitializeWithFile := nil;
          end
        else
          if Succeeded(ThumbnailProvider.QueryInterface(IPersistFile, PersistFile)) then
            try
              OleCheck(PersistFile.Load(PWideChar(AFileName), STGM_READ));
            finally
              PersistFile := nil;
            end
          else
            raise Exception.Create('Cannot initialize handler');

        OleCheck(ThumbnailProvider.GetThumbnail(ASize, Result, AAlpha));
      finally
        ThumbnailProvider := nil;
      end;
    finally
      ClassFactory := nil;
    end;
  finally
    FreeLibrary(DllModule);
  end;
end;
Denis Anisimov
  • 3,297
  • 1
  • 10
  • 18