windows - How to use SHCreateItemFromParsingName with names from the shell namespace? -


i using shcreateitemfromparsingname turn path ishellitem:

ishellitem parsename(string path) {     ishellitem shellitem;      hresult hr = shcreateitemfromparsingname(path, null, ishellitem, out shellitem);     if (failed(hr))          throw new ecomexception(hr);     return shellitem; } 

note: ishellitem introduced around 2006 provide handy wrapper around windows 95-era ishellfolder+pidl constructs. can ask ishellitem cough it's underlying ishellfolder , pidl iparentanditem.getparentanditem interface , method.

different things have different display names

i can ahold of well-known locations in shell namespace, , see absolute parsing (sigdn_desktopabsoluteparsing) , editing (sigdn_desktopabsoluteediting) display names:

| 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" | 

how parse them when user types in them in?

i can use ifileopendialog let user select 1 of these folders. i'd user able type

  • "c:\users"
  • "c:\windows\fonts"
  • "this pc"
  • "recycle bin"
  • "libraries"
  • "startup"
  • "fonts"

and able parse ishellitem.

the problem of paths not parsed shcreateitemfromparsingname:

  • shcreateitemfromparsingname("c:\"): parses
  • shcreateitemfromparsingname("c:\windows"): parses
  • shcreateitemfromparsingname(""): parses (but becomes "this pc")
  • shcreateitemfromparsingname("this pc"): fails
  • shcreateitemfromparsingname("recycle bin"): fails
  • shcreateitemfromparsingname("libraries"): fails
  • shcreateitemfromparsingname("onedrive"): fails
  • shcreateitemfromparsingname("libraries\documents"): fails
  • shcreateitemfromparsingname("network"): fails
  • shcreateitemfromparsingname("startup"): fails

meanwhile, ifileopendialog control program uses can parse them fine:

enter image description here

how can parse various special shell name places user might type in (that windows explorer , ifileopen dialog can parse) ishellitem folder?

the real question want user able have recent mru list contains things like:

  • c:\windows
  • recycle bin
  • this pc

and able parse them later.

it interesting debug explorer , see how it.

my suggestion is; if initial parse fails, prepend shell: path string , try parsing again shparsedisplayname. if set str_parse_shell_protocol_to_file_objects in bind context can bind special files. shell: protocol able parse internal/canonical name of special/known folders don't know if checks display name.

edit:

i had chance play around bit , shell: prefix not huge improvement because checks known folder canonical names:

pcwstr paths[] = {     text("c:\\"),     text("c:\\windows"),     text(""),     text("this pc"),     text("mycomputerfolder"), // canonical kf name     text("recycle bin"),     text("recyclebinfolder"), // canonical kf name     text("libraries"),     text("onedrive"),     text("libraries\\documents"),     text("network"),     text("networkplacesfolder"), // canonical kf name     text("startup"), };  oleinitialize(0); int pad = 0, fill, i; (i = 0; < arraysize(paths); ++i) pad = max(pad, lstrlen(paths[i])); (i = 1, fill = printf("%-*s | original | shell:   |\n", pad, ""); < fill; ++i) printf("-"); printf("\n"); (i = 0; < arraysize(paths); ++i) {     wchar buf[max_path], *p1 = null, *p2 = null;     ishellitem*psi;     hresult hr = shcreateitemfromparsingname(paths[i], null, iid_ishellitem, (void**) &psi);     if (succeeded(hr)) psi->getdisplayname(sigdn_desktopabsoluteparsing, &p1), psi->release();     wsprintf(buf, l"shell:%s", paths[i]);     hresult hr2 = shcreateitemfromparsingname(buf, null, iid_ishellitem, (void**) &psi);     if (succeeded(hr2)) psi->getdisplayname(sigdn_desktopabsoluteparsing, &p2), psi->release();     wprintf(l"%-*s | %.8x | %.8x | %s\n", pad, paths[i], hr, hr2, p2 && *p2 ? p2 : p1 ? p1 : l"");     cotaskmemfree(p1), cotaskmemfree(p2); } 

gives me output:

                    | original | shell:   | ------------------------------------------- c:\                 | 00000000 | 80070003 | c:\ c:\windows          | 00000000 | 80070003 | c:\windows                     | 00000000 | 80070003 | ::{20d04fe0-3aea-1069-a2d8-08002b30309d} pc             | 80070002 | 80070003 |  mycomputerfolder    | 80070002 | 00000000 | ::{20d04fe0-3aea-1069-a2d8-08002b30309d} recycle bin         | 80070002 | 80070003 |  recyclebinfolder    | 80070002 | 00000000 | ::{645ff040-5081-101b-9f08-00aa002f954e} libraries           | 80070002 | 00000000 | ::{031e4825-7b94-4dc3-b131-e946b44c8dd5} onedrive            | 80070002 | 80070003 |  libraries\documents | 80070002 | 80070002 |  network             | 80070002 | 80070003 |  networkplacesfolder | 80070002 | 00000000 | ::{f02c1a0d-be21-4350-88b0-7367fc96ef3c} startup             | 80070002 | 00000000 | c:\users\anders\appdata\roaming\microsoft\windows\start menu\programs\startup 

on windows 8 shcreateitemfromparsingname calls shparsedisplayname (with str_parse_and_create_item , str_parse_translate_aliases) microsoft have trouble separating parsing , display names in api.

if want stay away undocumented interfaces have add third pass check known folder display names. or alternatively raymond chen suggests in comments; parse every path component manually against item display names in ishellfolder.


Comments

Popular posts from this blog

.htaccess - First slash is removed after domain when entering a webpage in the browser -

Automatically create pages in phpfox -

c# - Farseer ContactListener is not working -