问题描述
我有一个表单路径
::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\Fonts
如果我在资源管理器地址栏中输入它,它会正确打开控制面板 - 字体.
If I enter this into the explorer address bar it correctly opens Control Panel - Fonts.
如何使用 ShellExecuteEx 或类似的东西(包含 guid 的路径)执行相同的操作?
How can I execute the same using ShellExecuteEx or something similar (a path containing guids)?
推荐答案
要打开此类 GUID 路径,您必须在路径前添加 shell:
协议:
To open such GUID pathes you have to prepend the shell:
protocol to the path:
shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\Fonts
请注意,GUID 路径经常在 Windows 版本之间变化,例如上述路径在我的 Windows 10 机器上不起作用.
Note that GUID pathes often change between Windows versions, for instance the above path doesn't work on my Windows 10 machine.
更好的方法是使用 已知文件夹 API 获取指向文件夹的 PIDL 并使用 ShellExecuteEx
打开该 PIDL:
A better approach is to use the known folder API to get a PIDL that points to the folder and open that PIDL using ShellExecuteEx
:
#include <iostream>
#include <windows.h>
#include <shellapi.h>
#include <atlbase.h> // CComHeapPtr
struct CComInit
{
HRESULT hr = E_FAIL;
CComInit() { hr = ::CoInitialize(nullptr); }
~CComInit() { if( SUCCEEDED(hr) ) ::CoUninitialize(); }
};
int main()
{
CComInit com;
if( FAILED( com.hr ) )
{
std::cout << "Failed to initialize COM, error: 0x" << std::hex << com.hr << '\n';
return static_cast<int>( com.hr );
}
CComHeapPtr<ITEMIDLIST> pidl;
HRESULT hr = ::SHGetKnownFolderIDList( FOLDERID_Fonts, KF_FLAG_DEFAULT, nullptr, &pidl );
if( FAILED( hr ) )
{
std::cout << "SHGetKnownFolderIDList failed with error 0x" << std::hex << hr << '\n';
return static_cast<int>( hr );
}
SHELLEXECUTEINFOW si{ sizeof(si) };
si.fMask = SEE_MASK_NOASYNC | SEE_MASK_IDLIST;
si.nShow = SW_SHOWDEFAULT;
si.lpVerb = L"open";
si.lpIDList = pidl;
if( !::ShellExecuteExW( &si ) )
{
DWORD err = ::GetLastError();
std::cout << "ShellExecuteExW failed with error " << err << '\n';
return static_cast<int>( err );
}
return 0;
}
注意事项:
- ATL 类
CComHeapPtr
是一个智能指针,它会在其析构函数中自动调用CoTaskMemFree()
以正确释放外壳分配的PIDL.如果您不想使用它,则必须手动调用CoTaskMemFree()
或使用您自己的 RAII 包装器来执行此操作. - 使用标志
SEE_MASK_NOASYNC
是因为该示例是一个控制台程序,它将在ShellExecuteEx
调用后立即退出.
- The ATL class
CComHeapPtr
is a smart pointer that automatically callsCoTaskMemFree()
in its destructor to correctly deallocate the PIDL that was allocated by the shell. If you don't want to use it, you have to callCoTaskMemFree()
manually or use your own RAII wrapper to do this. - The flag
SEE_MASK_NOASYNC
is used because the example is a console program that will exit immediately after theShellExecuteEx
call.
这篇关于ShellExecuteEx 引导路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!