lokimidgard
lokimidgard

Reputation: 1119

Using IShellBrowser::BrowseObject() in IShellFolder::EnumObjects()

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

Answers (1)

Rudolfs Bundulis
Rudolfs Bundulis

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

Related Questions