shell COM problems with Vista
-
This is a though one (no, really). I'm making a shell extension that implements infotip and thumbnail for cbz(zip) and cbr(rar) archives. For some COM-gods-only-known reason, it works flawlessly in XP but in Vista, behaviour is strange - infotip seems to work, but Vista loads dll only for showing infotip, and then immediately unloads it (observed in Process Explorer) and thumbnail extraction fails. :( When I make separate dlls (old code adapted from some examples) for infotip and thumbnail, they work fine in Vista (but it would be nice to kill 2 flies with 1 strike). If I use this Explorer lookalike for debugging, thumbnails are sometimes extracted but it often silently crashes. What am I doing wrong? (got ideas but not that much experience with COM :rolleyes: /learning by copy-paste). Thanks for your help in advance!:rose: The project skeleton was created with vc6 and further with vc9express+WDK ATL/WTL. Here is the complete project: http://www.autohotkey.net/~T800/TEMP/CBXshell.zip and quick peek of implementation:
class ATL_NO_VTABLE CCBXShell :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCBXShell,&CLSID_CBXShell>,
public IDispatchImpl<ICBXShell, &IID_ICBXShell, &LIBID_CBXSHELLLib>,
public ISupportErrorInfo,
public IPersistFile,
public IExtractImage2,
public IQueryInfo
{
public:
CCBXShell() {}BEGIN\_COM\_MAP(CCBXShell) COM\_INTERFACE\_ENTRY(ICBXShell) COM\_INTERFACE\_ENTRY(IPersistFile) COM\_INTERFACE\_ENTRY(IQueryInfo) COM\_INTERFACE\_ENTRY(IExtractImage) COM\_INTERFACE\_ENTRY(IExtractImage2) COM\_INTERFACE\_ENTRY(IDispatch) COM\_INTERFACE\_ENTRY(ISupportErrorInfo) END\_COM\_MAP() //DECLARE\_NOT\_AGGREGATABLE(CCBXShell) // Remove the comment from the line above if you don't want your object to // support aggregation. //\_ATL\_DEBUG\_ADDREF\_RELEASE\_IMPL(CCBXShell) DECLARE\_REGISTRY\_RESOURCEID(IDR\_CBXShell) DECLARE\_PROTECT\_FINAL\_CONSTRUCT() // IPersistFile STDMETHOD(Load)(LPCOLESTR wszFile, DWORD dwMode) { return m\_cbx.OnLoad(wszFile); } STDMETHOD(GetClassID)(LPCLSID clsid){return E\_NOTIMPL;} STDMETHOD(IsDirty)(VOID){return E\_NOTIMPL;} STDMETHOD(Save)(LPCOLESTR, BOOL){return E\_NOTIMPL;} STDMETHOD(SaveCompleted)(LPCOLESTR){return E\_NOTIMPL;} STDMETHOD(GetCurFile)(LPOLESTR FAR\*){return E\_NOTIMPL;} // IExtr
-
This is a though one (no, really). I'm making a shell extension that implements infotip and thumbnail for cbz(zip) and cbr(rar) archives. For some COM-gods-only-known reason, it works flawlessly in XP but in Vista, behaviour is strange - infotip seems to work, but Vista loads dll only for showing infotip, and then immediately unloads it (observed in Process Explorer) and thumbnail extraction fails. :( When I make separate dlls (old code adapted from some examples) for infotip and thumbnail, they work fine in Vista (but it would be nice to kill 2 flies with 1 strike). If I use this Explorer lookalike for debugging, thumbnails are sometimes extracted but it often silently crashes. What am I doing wrong? (got ideas but not that much experience with COM :rolleyes: /learning by copy-paste). Thanks for your help in advance!:rose: The project skeleton was created with vc6 and further with vc9express+WDK ATL/WTL. Here is the complete project: http://www.autohotkey.net/~T800/TEMP/CBXshell.zip and quick peek of implementation:
class ATL_NO_VTABLE CCBXShell :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCBXShell,&CLSID_CBXShell>,
public IDispatchImpl<ICBXShell, &IID_ICBXShell, &LIBID_CBXSHELLLib>,
public ISupportErrorInfo,
public IPersistFile,
public IExtractImage2,
public IQueryInfo
{
public:
CCBXShell() {}BEGIN\_COM\_MAP(CCBXShell) COM\_INTERFACE\_ENTRY(ICBXShell) COM\_INTERFACE\_ENTRY(IPersistFile) COM\_INTERFACE\_ENTRY(IQueryInfo) COM\_INTERFACE\_ENTRY(IExtractImage) COM\_INTERFACE\_ENTRY(IExtractImage2) COM\_INTERFACE\_ENTRY(IDispatch) COM\_INTERFACE\_ENTRY(ISupportErrorInfo) END\_COM\_MAP() //DECLARE\_NOT\_AGGREGATABLE(CCBXShell) // Remove the comment from the line above if you don't want your object to // support aggregation. //\_ATL\_DEBUG\_ADDREF\_RELEASE\_IMPL(CCBXShell) DECLARE\_REGISTRY\_RESOURCEID(IDR\_CBXShell) DECLARE\_PROTECT\_FINAL\_CONSTRUCT() // IPersistFile STDMETHOD(Load)(LPCOLESTR wszFile, DWORD dwMode) { return m\_cbx.OnLoad(wszFile); } STDMETHOD(GetClassID)(LPCLSID clsid){return E\_NOTIMPL;} STDMETHOD(IsDirty)(VOID){return E\_NOTIMPL;} STDMETHOD(Save)(LPCOLESTR, BOOL){return E\_NOTIMPL;} STDMETHOD(SaveCompleted)(LPCOLESTR){return E\_NOTIMPL;} STDMETHOD(GetCurFile)(LPOLESTR FAR\*){return E\_NOTIMPL;} // IExtr
Check in all your implementation for valid value. As her in OnGetLocation(const SIZE *prgSize, DWORD *pdwFlags) if( *prgSize &&*pdwFlags) { //your code } return E_FAIL; COM is a real pain. Good luck :thumbsup:
Press F1 for help or google it. Greetings from Germany
-
Check in all your implementation for valid value. As her in OnGetLocation(const SIZE *prgSize, DWORD *pdwFlags) if( *prgSize &&*pdwFlags) { //your code } return E_FAIL; COM is a real pain. Good luck :thumbsup:
Press F1 for help or google it. Greetings from Germany
Still nothing. I traced class members, but it seems that only infotip works ok. In XP it goes (while shown in Explorer sidepane, debug output):
IPersistFile::Load
IExtractImage2::GetLocation
IPersistFile::Load
IQueryInfo::GetInfoTip
IExtractImage2::GetDateStamp
IExtractImage::Extractbut in Vista CCBXShell class destructs immediately (commented code, left only IExtractImage stuff):
CCBXArchive::CCBXArchive
CCBXShell::CCBXShell
CCBXShell::~CCBXShell
CCBXArchive::~CCBXArchiveI tried to (un)comment various stuff, like class inheritance, interface parts, unrar dependency, everything I could come up with but to no avail. I know that IExtractimage::GetDateStamp is broken in Vista, I tried also with Win7 RC1 (got it in virtual machine) - no good. I still haven't tried to make IThumbnailProvider version (would be nice if I could make it more cross-windows). Anyway, I'm running out of nerves, will and (my free) time (I'll skip harder words about M$). X| I don't know if that misterious "com object aggregation" stuff might be relevant.
-
Still nothing. I traced class members, but it seems that only infotip works ok. In XP it goes (while shown in Explorer sidepane, debug output):
IPersistFile::Load
IExtractImage2::GetLocation
IPersistFile::Load
IQueryInfo::GetInfoTip
IExtractImage2::GetDateStamp
IExtractImage::Extractbut in Vista CCBXShell class destructs immediately (commented code, left only IExtractImage stuff):
CCBXArchive::CCBXArchive
CCBXShell::CCBXShell
CCBXShell::~CCBXShell
CCBXArchive::~CCBXArchiveI tried to (un)comment various stuff, like class inheritance, interface parts, unrar dependency, everything I could come up with but to no avail. I know that IExtractimage::GetDateStamp is broken in Vista, I tried also with Win7 RC1 (got it in virtual machine) - no good. I still haven't tried to make IThumbnailProvider version (would be nice if I could make it more cross-windows). Anyway, I'm running out of nerves, will and (my free) time (I'll skip harder words about M$). X| I don't know if that misterious "com object aggregation" stuff might be relevant.
Vista and Windows 7 should work the same way. I guess that the Micorosofties changed the implementation from XP to Vista. It wouldnt be the first (and the last) time someone had to program a solution for EVERY Windows-Version.:mad: :(( X|
Press F1 for help or google it. Greetings from Germany
-
Vista and Windows 7 should work the same way. I guess that the Micorosofties changed the implementation from XP to Vista. It wouldnt be the first (and the last) time someone had to program a solution for EVERY Windows-Version.:mad: :(( X|
Press F1 for help or google it. Greetings from Germany
In the end I gave up and adapted IThumbnailProvider sample from WinSDK. http://www.autohotkey.net/~T800/TEMP/CBXShell%204.0.0.2.rar I would say that M$ is internally using something else beside ATL for com and selling us their high-price pro-bloatware, because that sample uses previously undocumented, but yet availabe even in win2000, by-ordinal exported functions from Shlwapi.dll. Hmmm... this sample will come in handy :cool: , you can adapt it to your needs in 10 mins, instead losing time with ATL wizards. Now it all works OK, on XP and Vista (still gotta test x64), beside the fact that Explorer stubbornly caches/doesn't unload dll when it's not needed (but it's OK since (un)installer will do a reboot). I traced interface calls and it is incredible to see such M$-incompetence (parts of output from a few runs, just for an illustration), look at that inconsistent mess:
CCBXShell::CCBXShell
IInitializeWithFile::Initialize
CCBXArchive::OnLoad
IExtractImage::GetLocation
CCBXArchive::OnGetLocation
IThumbnailProvider::GetThumbnail
CCBXArchive::OnGetLocation
CCBXArchive::OnExtract
CCBXShell::~CCBXShellCCBXShell::CCBXShell
IInitializeWithFile::Initialize
CCBXArchive::OnLoad
IExtractImage::GetLocation
CCBXArchive::OnGetLocation
IThumbnailProvider::GetThumbnail
CCBXArchive::OnGetLocation
CCBXArchive::OnExtract
CCBXShell::~CCBXShellCCBXShell::CCBXShell
IInitializeWithFile::Initialize CCBXArchive::OnLoad
IExtractImage::GetLocation CCBXArchive::OnGetLocation
IThumbnailProvider::GetThumbnail CCBXArchive::OnGetLocation CCBXArchive::OnExtractCCBXShell::CCBXShell
IInitializeWithFile::Initialize CCBXArchive::OnLoad CCBXArchive::OnGetInfoTip
CCBXShell::~CCBXShell
CCBXShell::~CCBXShell -
Vista and Windows 7 should work the same way. I guess that the Micorosofties changed the implementation from XP to Vista. It wouldnt be the first (and the last) time someone had to program a solution for EVERY Windows-Version.:mad: :(( X|
Press F1 for help or google it. Greetings from Germany
It looks that Vista is very stubborn about thumbnails. It seems that my first version (the one with IExtractimage) works after all (go figure). I forcefully deleted Vista thumbnail cache files (inside C:\Users\T800\AppData\Local\Microsoft\Windows\Explorer\) and now it seems to work OK. (I needed a bigger hammer :cool: ) Btw, I think that IThumbnailProvider example from SDK still has bugs, but I'm not wasting my time with it now. Merry Xmas and happy New year! :rose: