c++ - 为什么这个 COM 代码会泄漏?

标签 c++ windows com atl windows-shell

我正在维护一个使用 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 向我展示了我似乎每次都在泄漏 pFolderpShellWindow 实例这个运行的时间。我无法弄清楚为什么会发生这种情况,因为据我所知这些已正确发布。谁能看到我错过了什么?

最佳答案

你释放pShellWindowsCoUninitialize 之后,这是不正确的。

其余接口(interface)似乎发布正常。请注意,通过使用 CComQIPtr,您可以大大改善清洁和可读性而不是 QueryInterface , 并且根本不使用原始指针( BSTR , IFoo* )并将它们替换为智能自动释放包装器。

pFolder如果 Item 也可能会泄漏调用成功但返回的代码不是S_OK .同样,使用 CComPtr<IFolder>而不是 IFolder*会立即解决这个问题,甚至不会引起任何注意。

关于c++ - 为什么这个 COM 代码会泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16355466/

相关文章:

c++ - *ptr1++ = *ptr2++ 后按索引访问

c++ - 使用QT查看来自相机的流图像

c++ - 将 kde 应用程序移植到 windows

windows - 为什么 Docker 卷无法在 Windows 上运行

c++ - 在不使用对象的情况下调用类方法?

c++ - 如何在windows平台上使用c++信号

c++ - vfptr/vftable 在类析构函数调用父析构函数时更改基类型

c# - 从 COM .dll 获取错误 '80070002'

windows - 在所有未使用的情况下,进程外 COM 服务器最终是否应该停止?

c# - 为 COM Interop 公开 dll