【发布时间】:2017-03-23 03:01:49
【问题描述】:
我正在使用SHCreateItemFromParsingName 将路径 转换为IShellItem:
IShellItem ParseName(String path)
{
IShellItem shellItem;
HRESULT hr = SHCreateItemFromParsingName(path, null, IShellItem, out shellItem);
if (Failed(hr))
throw new ECOMException(hr);
return shellItem;
}
注意:
IShellItem是在 2006 年左右引入的,它为 Windows 95 时代的IShellFolder+pidl结构提供了一个方便的包装器。您甚至可以通过IParentAndItem.GetParentAndItem接口和方法要求IShellItem咳出它的底层IShellFolder和pidl。
不同的事物有不同的显示名称
我可以在 shell 命名空间中找到一些众所周知的位置,并查看它们的绝对解析 (SIGDN_DESKTOPABSOLUTEPARSING) 和编辑 (SIGDN_DESKTOPABSOLUTEEDITING) 显示名称:
| Path | Editing | Parsing |
|---|---|---|
| C:\ | "C:" | "C:" |
| C:\Windows | "C:\Windows" | "C:\Windows" |
| Desktop | "Desktop" | "C:\Users\Ian\Desktop" |
| Computer | "This PC" | "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" |
| Recycle Bin | "Recycle Bin" | "::{645FF040-5081-101B-9F08-00AA002F954E}" |
| Documents Library | "Libraries\Documents" | "::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms" " |
| Startup | "C:\Users\Ian\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" | "C:\Users\Ian\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" |
用户输入时如何解析?
我可以使用IFileOpenDialog 让用户选择其中一个文件夹。但我真的希望用户能够输入
- “C:\Users”
- “C:\Windows\Fonts”
- “这台电脑”
- “回收站”
- “库”
- “启动”
- “字体”
并能够将其解析为 IShellItem。
问题是某些路径没有被SHCreateItemFromParsingName解析:
-
SHCreateItemFromParsingName("C:\"):解析 -
SHCreateItemFromParsingName("C:\Windows"):解析 -
SHCreateItemFromParsingName(""):解析(但变成“这台电脑”) -
SHCreateItemFromParsingName("This PC"):失败 -
SHCreateItemFromParsingName("Recycle Bin"):失败 -
SHCreateItemFromParsingName("Libraries"):失败 -
SHCreateItemFromParsingName("OneDrive"):失败 -
SHCreateItemFromParsingName("Libraries\Documents"):失败 -
SHCreateItemFromParsingName("Network"):失败 -
SHCreateItemFromParsingName("Startup"):失败
同时,我的程序使用的 IFileOpenDialog 控件可以很好地解析它们:
如何将用户可能键入的各种特殊 shell 名称位置(Windows 资源管理器和 IFileOpen 对话框可以解析)解析为该文件夹的 IShellItem?
真正的问题是我希望用户能够拥有一个最近的 MRU 列表,其中包含以下内容:
- C:\Windows
- 回收站
- 这台电脑
并且能够在以后解析它们。
【问题讨论】:
-
注意,所有失败的东西都直接在桌面下。我猜资源管理器在桌面文件夹上使用
IShellFolder::ParseDisplayName。 -
您可以有 2 个 MRU 列表。第一个将包含 UI 字符串(“This PC”),第二个将包含用于解析的字符串(“::{20D04FE0-3AEA-1069-A2D8-08002B30309D}”)。当用户选择 UI 字符串时,您将使用相应的解析字符串。
-
这基本上是未解决的stackoverflow.com/q/37000602/3501 的副本,但恕我直言,这个问题已经是更高质量的问题了。
-
那些不解析名称。它们是显示名称。
-
Explorer 正在做额外的工作。基本上,它会查找显示名称与用户键入的值匹配的孩子。 SHParseDisplayName 只能解析本应被解析回来的名称 (SHGDN_FORPARSING)。如果您要求显示名称,那么再次找到它的唯一方法就是寻找匹配项。 (您可以有多个具有相同显示名称的项目。显示名称不明确。)
标签: windows winapi windows-shell