Reputation: 1119
I have a Namespace Extension that makes webcalls to show its content.
When the Explorer wants to display the content of a folder it calls EnumObjects
on my implementation. When there is an error making the webcall I want to return the User to the root of my NSE. Currently I call following code:
LPITEMIDLIST pidl = /*The piddle to navigate to, in my case root*/;
IShellBrowser* browser = (IShellBrowser*)SendMessage(m_hWnd, (WM_USER + 7), 0, 0);
if (browser != NULL) {
hr = browser->BrowseObject(pidl, SBSP_SAMEBROWSER | SBSP_ABSOLUTE);
}
Sometimes the method call to BrowseObject
fails with Invalid Access exception (x0000005).
We also used a variant that would use following variant:
hr = GetSite(IID_IServiceProvider, (void**)&serviceProvider);
if (FAILED(hr))
return false;
IShellBrowser *browser;
hr = serviceProvider->QueryService(SID_SShellBrowser, &browser);
if(FAILED(hr))
return false;
The site is obtaind through the interface IObjectWithSite
. This also faild randomly. What I noticed was that when the webcall failed m_site
was NULL
.
EnumObject
is called in a seperate thread from the explorer, to the UI will not freeze when I do the webcall. I assume I may not call Browse object from the thread that enums the folder, but how can I call browse on the correct thread?
Calling the BrowseObject
in a new thread and wait 1 seccond will not lead to a crash. But I would not consider this hack as a valid solution.
Upvotes: 0
Views: 354
Reputation: 11934
It seems that you are not properly adding a reference to the COM interface you are using, which COULD cause it to be actually destroyed. So either use CComPtr, or at least call AddRef
/ Release
to hold a valid reference to the object.
Also if multiple threads are used, are you calling CoInitialize
from all of them?
Upvotes: 2