limelect 48 Posted March 19, 2019 I am trying to translate "Libraries\Pictures\My Pictures\" for example to the directory "C:\Users\LimElect\Pictures" I am using var LShellItem: IShellItem; LPlace: TFavoriteLinkItem; begin if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'), nil, StringToGUID(SID_IShellItem), LShellItem)) then begin Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<< here LShellItem is nil !! end; This dose not work , any idea? I took the above from VCL.dialogs P.S Using FileOpenDialog and return FileOpenDialog1.ShellItem this works. BUT I DO NOT WANT TO EXECUTE. I just want the directory NOT a file !! Share this post Link to post
toms 29 Posted March 19, 2019 Does this help? http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.IOUtils.TPath.GetPicturesPath Share this post Link to post
limelect 48 Posted March 19, 2019 (edited) NO because picture is only an example. However you gave me an idea to decode (i do not like it) a WORD in the explorer address to TPath.Get.... However i would like a nicer approach Edited March 19, 2019 by limelect Share this post Link to post
Remy Lebeau 1393 Posted March 19, 2019 (edited) 6 hours ago, limelect said: I am trying to translate "Libraries\Pictures\My Pictures\" for example to the directory "C:\Users\LimElect\Pictures" When working with Libraries, you should use the IShellLibrary interface to query them. However, in this particular example, the correct way to get the path to the user's Pictures folder is to use SHGetFolderPath(CSIDL_MYPICTURES) or SHGetKnownFolderPath(FOLDERID_Pictures) instead. Quote I am using if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'), nil, StringToGUID(SID_IShellItem), LShellItem)) then begin Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<< here LShellItem is nil !! end; LShellItem can't be nil if SHCreateItemFromParsingName() returns success. Edited March 19, 2019 by Remy Lebeau Share this post Link to post
limelect 48 Posted March 20, 2019 @Remy Lebeau I know most of the answer. It seem i did not ask the right way. The library section on the drive is only TEXT referring to c:/users/.... what i want is a way to translate this TEXT to c:/users/... My picture is just an EXAMPLE of my NEED. I tried Using FileOpenDialog that returns FileOpenDialog1.ShellItem this works. !!!!! BUT I DO NOT WANT TO EXECUTE. I just want the directory NOT a file !!!! I need the software behind FileOpenDialog ON A DIRECTORY (not a file) without the FileOpenDialog.execute. this is why i tried SHCreateItemFromParsingName I hop it clarified my need. Share this post Link to post
Remy Lebeau 1393 Posted March 20, 2019 7 hours ago, limelect said: @Remy Lebeau I know most of the answer. It seem i did not ask the right way. The library section on the drive is only TEXT referring to c:/users/.... what i want is a way to translate this TEXT to c:/users/... Like I said, use the Shell Library API for that. See Windows Libraries and Using Libraries in your Program for more details. 7 hours ago, limelect said: I tried Using FileOpenDialog that returns FileOpenDialog1.ShellItem this works. !!!!! BUT I DO NOT WANT TO EXECUTE. I just want the directory NOT a file !!!! I need the software behind FileOpenDialog ON A DIRECTORY (not a file) without the FileOpenDialog.execute. this is why i tried SHCreateItemFromParsingName You don't need to repeat yourself. You made yourself perfectly clear the first time you said that. Share this post Link to post
Rudy Velthuis 91 Posted March 20, 2019 On 3/19/2019 at 10:21 AM, limelect said: I am trying to translate "Libraries\Pictures\My Pictures\" for example to the directory "C:\Users\LimElect\Pictures" I am using var LShellItem: IShellItem; LPlace: TFavoriteLinkItem; begin if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'), nil, StringToGUID(SID_IShellItem), LShellItem)) then begin Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<< here LShellItem is nil !! end; This dose not work , any idea? I took the above from VCL.dialogs P.S Using FileOpenDialog and return FileOpenDialog1.ShellItem this works. BUT I DO NOT WANT TO EXECUTE. I just want the directory NOT a file !! I don't have a ready implementation right now, but Start with SHGetDesktopFolder. This returns an IShellFolder. Use IShellFolder.ParseDisplayName and see if you can get it to parse your directory. That should provide an ItemIDList. Now you can use those two to get the proper name. Share this post Link to post
Remy Lebeau 1393 Posted March 21, 2019 (edited) 21 hours ago, Rudy Velthuis said: I don't have a ready implementation right now, but Start with SHGetDesktopFolder. This returns an IShellFolder. Use IShellFolder.ParseDisplayName and see if you can get it to parse your directory. That should provide an ItemIDList. Now you can use those two to get the proper name. That last step does not require the IShellFolder as the returned ItemIDList will be an absolute PIDL that can be passed to SHGetPathFromIDList(). But, this solution really isn't much different than using SHCreateItemFromParsingName() and ShellItemFileSystemPath() with an IShellItem instead of an ItemIDList. Edited March 21, 2019 by Remy Lebeau Share this post Link to post
Rudy Velthuis 91 Posted March 21, 2019 (edited) 1 hour ago, Remy Lebeau said: That last step does not require the IShellFolder as the returned ItemIDList will be an absolute PIDL that can be passed to SHGetPathFromIDList(). But, this solution really isn't much different than using SHCreateItemFromParsingName() and ShellItemFileSystemPath() with an IShellItem instead of an ItemIDList. My solution already worked in Delphi 4. Then, there was no SHGetPathFromIDList() yet. And the other solution was not possible at all. <g> Edited March 21, 2019 by Rudy Velthuis Share this post Link to post
limelect 48 Posted March 21, 2019 (edited) @Rudy Velthuis I tried very simple 2 line of your suggestion var Attr, Eaten: ULONG; PathIdList: PItemIdList; DesktopFolder: IShellFolder; if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin //Libraries\Pictures\ if Succeeded(DesktopFolder.ParseDisplayName(0, nil, 'c:\', Eaten, PathIdList, Attr)) then begin end; If i use 'Libraries\Pictures\' for path i get PathIdList=nil If i use 'c:\' for path i get PathIdList <>nil i am stuck again Can you put your suggestion source here ? With what dir librery text did you try your solution? Edited March 21, 2019 by limelect Share this post Link to post
Rudy Velthuis 91 Posted March 21, 2019 12 minutes ago, limelect said: @Rudy Velthuis I tried very simple 2 line of your suggestion var Attr, Eaten: ULONG; PathIdList: PItemIdList; DesktopFolder: IShellFolder; if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin //Libraries\Pictures\ if Succeeded(DesktopFolder.ParseDisplayName(0, nil, 'c:\', Eaten, PathIdList, Attr)) then begin end; If i use 'Libraries\Pictures\' for path i get PathIdList=nil If i use 'c:\' for path i get PathIdList <>nil i am stuck again Can you put your suggestion source here ? With what dir librery text did you try your solution? What happens if you use 'C:\Libraries\Pictures' or 'C:\Windows' as path? You need a full path and the PItemIDList for C:\ is, AFAIK, indeed nil. Share this post Link to post
limelect 48 Posted March 21, 2019 (edited) @Rudy Velthuis Libraries\Pictures\My Pictures is OK I tried C:\Libraries\Pictures NOT OK. this is not logical since there in NO such directory. Just go to explorer and see how Explorer open 'libraries' and more Edited March 21, 2019 by limelect Share this post Link to post
Rudy Velthuis 91 Posted March 21, 2019 (edited) 14 minutes ago, limelect said: @Rudy Velthuis Libraries\Pictures\My Pictures is OK I tried C:\Libraries\Pictures NOT OK. this is not logical since there in NO such directory. Just go to explorer and see how Explorer open 'libraries' and more 'C:\Libraries\Pictures' does not work for me either, but 'C:\Users\Rudy\Pictures' does. Note that a folder is not necessarily a physical directory on a physical medium, and that a display name can differ from the exact directory name as well. Libraries is such a virtual folder. It does not exist as such on disk and does not have a PItemIDList, AFAIK. Edited March 21, 2019 by Rudy Velthuis Share this post Link to post
limelect 48 Posted March 21, 2019 @Rudy Velthuis sure no problem for that C:\Users\Rudy\Pictures. Since this is your directory for pictures . But that where i started to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures THIS IS MY PROBLEM !!! Share this post Link to post
Rudy Velthuis 91 Posted March 21, 2019 28 minutes ago, limelect said: @Rudy Velthuis sure no problem for that C:\Users\Rudy\Pictures. Since this is your directory for pictures . But that where i started to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures THIS IS MY PROBLEM !!! Ok, your problem was not entirely clear to me. Share this post Link to post
Attila Kovacs 629 Posted March 21, 2019 does this help you to understand how "libraries" work? cd %appdata%\Microsoft\Windows\Libraries Share this post Link to post
Remy Lebeau 1393 Posted March 21, 2019 (edited) 2 hours ago, Rudy Velthuis said: Libraries is such a virtual folder. It does not ... have a PItemIDList, AFAIK. EVERYTHING in the Shell has a PIDL, relative to the Shell root. In this case, Libraries is not part of the file system, so you can't get its PIDL from parsing a file system path. The correct way to get the Libraries PIDL is to use SHGetKnownFolderIDList(FOLDERID_Libraries) instead. Edited March 21, 2019 by Remy Lebeau 1 Share this post Link to post
Remy Lebeau 1393 Posted March 21, 2019 (edited) 2 hours ago, limelect said: Since this is your directory for pictures . But that where i started to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures THIS IS MY PROBLEM !!! I've already answered this for you. You need to use the IShellLibrary interface to get the filesystem path(s) that a given Library points to. Why do you keep ignoring me on this? You need to obtain the IShellLibrary interface for "Libraries\Pictures" first, Then you can call the IShellLibrary::GetFolders() method asking it for an IShellItemArray interface, Then you can the IShellItemArray::EnumItems() method to get an IEnumShellItems interface, Then you can enumerate it to access the individual IShellItem interfaces, And finally call IShellItem::GetDisplayName() asking for SIGDN_FILESYSPATH. This is all documented on MSDN. Edited March 21, 2019 by Remy Lebeau 1 Share this post Link to post
limelect 48 Posted March 22, 2019 @Remy Lebeau I will see how to apply your idea. Let me (if you allow ) how i got to this situation. I have a free program http://limelect.com/downloads/explorer-list/ which you can go to any EXPLORER address fast. I am adding to it explore HISTORY. (why ? because some time i forget where i was in explorer). when i go into a directory i get the TEXT in the explorer bar And then if i need it letter i use it. If i have an address as "c:\...." that not a problem. However libraries... this where my problem start. Thanks in any case Share this post Link to post
Attila Kovacs 629 Posted March 22, 2019 (edited) @limelect In this case you could cache as a lookup table the entries from: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions and fire the explorer for example with: start shell:PicturesLibrary or explorer shell:PicturesLibrary where PicturesLibrary is the example, one element from the FolderDescriptions Then you will land there where you was and not in its translated dir. Edited March 22, 2019 by Attila Kovacs Share this post Link to post
limelect 48 Posted March 22, 2019 (edited) @Attila Kovacs your solution mite work but in my case i cannot use . http://limelect.com/downloads/explorer-list/ My software opens the same ! explorer page to a new location !! i do NOT open a new page unless i want it. I need the real address P.S Try my software it is very useful to us programmers and many people downloaded it. I will try Remy solution Edited March 22, 2019 by limelect Share this post Link to post
Attila Kovacs 629 Posted March 22, 2019 (edited) @limelect ok, sorry but I'm not operating with explorer at all. I'm using Far Manager. btw. you could lookup libraries/pictures from the mentioned list and fire the same location in a new explorer window without knowing its real location. Edited March 22, 2019 by Attila Kovacs Share this post Link to post
limelect 48 Posted March 22, 2019 @Remy Lebeau Thank you very much every body. From Remy who gave me a starting point i found what i NEED. It is MustangpeakVirtualShell-2.7.0\Demos\Namespace Browser It dose exactly my need. Thanks again Share this post Link to post
Rudy Velthuis 91 Posted March 22, 2019 (edited) 22 hours ago, Remy Lebeau said: EVERYTHING in the Shell has a PIDL, relative to the Shell root. In this case, Libraries is not part of the file system, so you can't get its PIDL from parsing a file system path. The correct way to get the Libraries PIDL is to use SHGetKnownFolderIDList(FOLDERID_Libraries) instead. Ok, but exactly that (get a PIDL from a file system path) seems to be what OP wants. Edited March 22, 2019 by Rudy Velthuis Share this post Link to post