我有一个命名空间扩展,可以通过网络调用显示其内容。
当资源管理器想要显示文件夹的内容时,它将在我的实现中调用EnumObjects
。进行网络通话时出错,我想将用户返回到我的NSE的根目录。目前,我调用以下代码:
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);
}
有时,由于无效访问异常(x0000005),对BrowseObject
的方法调用失败。
我们还使用了将使用以下变体的变体:
hr = GetSite(IID_IServiceProvider, (void**)&serviceProvider);
if (FAILED(hr))
return false;
IShellBrowser *browser;
hr = serviceProvider->QueryService(SID_SShellBrowser, &browser);
if(FAILED(hr))
return false;
通过接口IObjectWithSite
获得该站点。这也随机失败了。我注意到的是,当网络通话失败m_site
时是NULL
。
EnumObject
是在与浏览器不同的线程中调用的,当我进行网络通话时,UI不会冻结。我假设我可能不会从枚举该文件夹的线程中调用“浏览对象”,但是如何在正确的线程上调用“浏览”?
在新线程中调用BrowseObject
并等待1秒钟不会导致崩溃。但是我不认为这种黑客攻击是有效的解决方案。
答案 0 :(得分:2)
似乎您没有正确地添加对所用COM接口的引用,这可能会导致它实际上被销毁。因此,要么使用CComPtr,要么至少调用AddRef
/ Release
来持有对该对象的有效引用。
如果使用了多个线程,您是否要从所有线程中调用CoInitialize
?