详细背景
我的项目是在 Windows 资源管理器中创建一个图标来访问远程位置,并使 Windows 上的导航与本地文件系统的导航相同。
这工作正常,包括当该位置不再可用时在 Windows 资源管理器中添加和删除图标。但是,如果在删除图标之前在此位置打开 Windows 资源管理器,它会继续显示该图标,并且那里的任何交互都会导致错误。
我的目标是确保不会发生这种情况:如果该位置被删除,使任何 Windows 资源管理器实例打开到即将删除的位置导航到默认位置(示例)。
已经完成的事情
访问打开的 Windows 资源管理器实例正常,因为获取它们打开位置的路径。我按照这些说明操作,效果很好。
供参考,这是迄今为止我的代码:
std::vector<IWebBrowserApp*> getOpenWindowsExplorers()
{
std::vector<IWebBrowserApp*> openExplorers;
IShellWindows *psw;
if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL,
IID_IShellWindows, (void**)&psw))) {
VARIANT v;
V_VT(&v) = VT_I4;
IDispatch *pdisp;
BOOL fFound = FALSE;
for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK;V_I4(&v)++)
{
IWebBrowserApp *pwba;
if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba)))
{
openExplorers.push_back(pwba);
}
pdisp->Release();
}
psw->Release();
}
return openExplorers;
}
QString getCurrentOpenFolder(IWebBrowserApp* explorer)
{
QString folderPath;
IServiceProvider *psp;
if (SUCCEEDED(explorer->QueryInterface(IID_IServiceProvider, (void**)&psp)))
{
IShellBrowser *psb;
if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb)))
{
IShellView *psv;
if (SUCCEEDED(psb->QueryActiveShellView(&psv)))
{
IFolderView *pfv;
if (SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv)))
{
IPersistFolder2 *ppf2;
if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2)))
{
LPITEMIDLIST pidlFolder;
if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder)))
{
TCHAR g_szPath[MAX_PATH];
if (SHGetPathFromIDList(pidlFolder, g_szPath))
{
folderPath = QString::fromWCharArray(g_szPath);
}
CoTaskMemFree(pidlFolder);
}
ppf2->Release();
}
pfv->Release();
}
psv->Release();
}
psb->Release();
}
psp->Release();
}
return folderPath;
}
但是我找不到任何关于如何设置Windows资源管理器路径的文档,无论是官方的还是非官方的。
到目前为止我发现了什么
实现我想要的最好方法是什么?
您可以使用 IWebBrowser2::Navigate2 方法,如下所示:
int main()
{
CoInitialize(nullptr);
{
// build the optional VARIANT
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/e93f90dc-8afb-434f-afa9-94f8564fe19b
VARIANT optional;
VariantInit(&optional);
V_VT(&optional) = VT_ERROR;
V_I4(&optional) = DISP_E_PARAMNOTFOUND;
IShellWindows* windows;
if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&windows))))
{
long count;
windows->get_Count(&count);
for (auto i = 0; i < count; i++)
{
VARIANT index;
VariantInit(&index);
V_VT(&index) = VT_I4;
V_I4(&index) = i;
IDispatch* obj;
if (SUCCEEDED(windows->Item(index, &obj)))
{
IWebBrowser2* app;
if (SUCCEEDED(obj->QueryInterface(IID_PPV_ARGS(&app))))
{
// get a PIDL from a path
// note pidl could represent a virtual folder too
auto pidl = ILCreateFromPath(L"c:\\temp");
if (pidl)
{
// build a VARIANT from the PIDL
VARIANT url;
VariantInit(&url);
if (SUCCEEDED(InitVariantFromBuffer(pidl, ILGetSize(pidl), &url))) // propvarutil.h
{
app->Navigate2(&url, &optional, &optional, &optional, &optional);
}
VariantClear(&url);
ILFree(pidl);
}
app->Release();
}
obj->Release();
}
VariantClear(&index);
}
windows->Release();
}
}
CoUninitialize();
return 0;
}