我正在维护一个使用 Windows 资源管理器覆盖图标的应用程序。偶尔一些操作需要我强行刷新特定文件夹的资源管理器 View 。我这样做是使用以下使用 COM 的函数:
void RefreshExplorerView(CString strPath)
{
CComPtr<IShellWindows> pShellWindows;
CoInitialize(NULL);
if(SUCCEEDED(pShellWindows.CoCreateInstance(CLSID_ShellWindows)))
{
IDispatch* pFolder=NULL;
VARIANT variant;
V_VT(&variant) = VT_I4;
for(V_I4(&variant) = 0; pShellWindows->Item(variant, &pFolder) == S_OK; V_I4(&variant)++)
{
CComPtr<IWebBrowserApp> pWebBrowserApp;
if(SUCCEEDED(pFolder->QueryInterface(IID_PPV_ARGS(&pWebBrowserApp))))
{
BSTR LocationURL = NULL;
pWebBrowserApp->get_LocationURL(&LocationURL);
if(LocationURL != NULL && strPath.CompareNoCase(LocationURL) == 0)
{
CComPtr<IServiceProvider> pServiceProvider;
if(SUCCEEDED(pWebBrowserApp->QueryInterface(IID_PPV_ARGS(&pServiceProvider))))
{
CComPtr<IShellBrowser> pShellBrowser;
if(SUCCEEDED(pServiceProvider->QueryInterface(IID_PPV_ARGS(&pShellBrowser))))
{
IShellView* pShellView;
if(SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
{
pShellView->Refresh();
pShellView->Release();
}
}
}
}
SysFreeString(LocationURL);
}
pFolder->Release();
pFolder = NULL;
}
}
CoUninitialize();
}
我注意到,当我的程序定期进行此刷新时,它的大小会缓慢增长,并且 UMDH 向我展示了我似乎每次都在泄漏 pFolder
和 pShellWindow
实例这个运行的时间。我无法弄清楚为什么会发生这种情况,因为据我所知这些已正确发布。谁能看到我错过了什么?
最佳答案
你释放pShellWindows
在 CoUninitialize
之后,这是不正确的。
其余接口(interface)似乎发布正常。请注意,通过使用 CComQIPtr
,您可以大大改善清洁和可读性而不是 QueryInterface
, 并且根本不使用原始指针( BSTR
, IFoo*
)并将它们替换为智能自动释放包装器。
pFolder
如果 Item
也可能会泄漏调用成功但返回的代码不是S_OK
.同样,使用 CComPtr<IFolder>
而不是 IFolder*
会立即解决这个问题,甚至不会引起任何注意。
关于c++ - 为什么这个 COM 代码会泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16355466/