我认为一个人应该做this https://stackoverflow.com/questions/3572220/recognize-windows-shell-special-folder-i-e-get-its-csidl-via-its-pidl-now-de比较 PIDL:IShellFolder::CompareIDs()。
特别是,我试图检测给定的绝对 PIDL(或相对)是否是控制面板的 PIDL。
然而,在实践中,我最终得到了两个 PIDL,IShellFolder::CompareIDs() 声称它们不相等,而它们应该相等(查看每个 PIDL,我可以看到我们确实在查看控制面板) 。
基本上,我通过以下方式获取控制面板的绝对 PIDL:
PIDL iidControlPanel = nullptr;
SHGetSpecialFolderLocation(hwnd, CSIDL_CONTROLS, &iidControlPanel);
然后像这样比较传入的枚举 shell 对象(请参阅here https://stackoverflow.com/questions/14286833/how-to-detect-if-a-given-pidl-is-actually-a-zip-file-or-similar对于上下文 - 简而言之,这是查看枚举 CMFCShellTreeCtrl 内的桌面 shell 命名空间的结果):
bool bIsControlPanel = CompareAbsolutePIDLs(iidControlPanel, pItem->pidlFQ);
作为参考,这里是比较函数:
bool CompareAbsolutePIDLs(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
{
CComPtr<IShellFolder> ishDesk;
SHGetDesktopFolder(&ishDesk);
HRESULT hr = ishDesk->CompareIDs(SHCIDS_CANONICALONLY, pidl1, pidl2);
return SUCCEEDED(hr) && HRESULT_CODE(hr) == 0;
}
在调试器中,我可以看到每个返回的 GetDisplayName() :
"::{26EE0668-A00A-44D7-9371-BEB064C98683}\0"
"::{26EE0668-A00A-44D7-9371-BEB064C98683}"
在这里您可以看到 PIDL 的十六进制转储:
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *0c* 00
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *00* 00
除了倒数第二个值(00 与 0c)之外,底层 PIDLS 也是二进制相同的。我目前不知道为什么它们不同,或者我能做些什么来解决这个问题?!
问题
- 是否有另一种方法来获取控件的 PIDL,而不包含看似虚假的额外空字节?
- 或者,是否有更好的方法来获取枚举项的PIDL(CMFCShellTreeCtrol获取绝对PIDL的方式是否存在不足,导致无法包含最终的空字节?)
- 有没有办法获取控制面板作为相对 PIDL,然后将其与相对枚举 PIDL(我也有)进行比较?
- ???