benners

Resolving Windows Special Folders

9 posts in this topic

I am using a FileSelectFolder dialog to allows users to select folders. The folders are then stored in an ini file. When loading the program a check is run to see if the folders still exist. With most folders there is a path stored but some special folders save as

Music=::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Music.library-ms

or 

Documents=::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms

Shellexecute opens these but the FileExists check returns a no. What I am trying to find out is if there is a way to parse or resolve this string to a known folder id that can be used with _WinAPI_ShellGetKnownFolderPath like the Documents library below, or if there is some object method or property that can be explited to return the full path.

_WinAPI_ShellGetKnownFolderPath($FOLDERID_DocumentsLibrary)

For instance, I can get the folder name like so

Local $s_Path = '::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms'
MsgBox(0,'', SpecialFolders_GetSelfName($s_Path))

Func SpecialFolders_GetSelfName($s_Path)
     Local $objShell = ObjCreate("Shell.Application")
     if not IsObj($objShell) then Return ''

     Return  $objShell.NameSpace($s_Path).Self.Name
EndFunc   ;==>_Special_Folders

but despite searching I haven't been able to get the full path.

Share this post


Link to post
Share on other sites



I am only seeing "Documents" in the msgbox when I run:

Local $s_Path = '::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms'
MsgBox(0,'', SpecialFolders_GetSelfName($s_Path))

Func SpecialFolders_GetSelfName($s_Path)
     Local $objShell = ObjCreate("Shell.Application")
     if not IsObj($objShell) then Return ''

     Return  $objShell.NameSpace($s_Path).Self.Name
EndFunc   ;==>_Special_Folders

Can you show your #includes for the above code? Is the location of the ::{031E.... in the registry? Is it in the app data folder of the user directory? I need to know so I can try it locally.


Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Share this post


Link to post
Share on other sites

Hi, in the code the ::{031E.. part is retrieved from a FileSelectFolder dialog box. I normally create snippet scripts to test functions if I possible, and this is one. Once I can get the full path for any special folders selected I then add it to the main script. There are no #includes that are needed for this to run.

Run the code and select the Documents sub folder under the Libraries folder. This is on Win 7

; users chooses a folder
$s_FileName = FileSelectFolder('Please Select The Folder...', '', 3, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")

; this gets the folder objects name. I use this to save to the ini as the key string
; i.e I want it so save as below so I can check its existance
;[Folders]
; Documents=C:\Users\Benners\AppData\Roaming\Microsoft\Windows\Libraries\Documents.library-ms
;
; but the file path saves as
;[Folders]
; Documents=::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms

MsgBox(0,'', SpecialFolders_GetSelfName($s_FileName))

; the text returned from SpecialFolders_GetSelfName is then added to a menu as a menu item. When
; the item is selected it opens explorer at the folders location

; trimmimg the returned $s_FileName as you would a normal file\folder path will return Documents.library-ms
; return the name of the file object
Func SpecialFolders_GetSelfName($s_Path)
     Local $objShell = ObjCreate("Shell.Application")
     if not IsObj($objShell) then Return ''

     Return  $objShell.NameSpace($s_Path).Self.Name
EndFunc   ;==>_Special_Folders

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

OK I think I have got it. To get the fullpath you need to remove SpecialFolders_GetSelfName like this

MsgBox(0,'', $s_FileName)

Am I understanding what you are looking for correctly?

Edited by computergroove

Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Hi computergroove, I am trying to get the full path but the filename returned isn't always a proper path.

If I select The WIndows folder using the dialog box the $s_FileName value will be "C:\Windows". The text I want to be displayed on my menu item will be "Windows", I can get this from the path by using

#include <WinAPIShPath.au3>

; users chooses a folder
$s_FileName = FileSelectFolder('Please Select The Folder...', '', 3, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")

MsgBox(0,'', _WinAPI_PathStripPath($s_FileName))

Then Windows is displayed on the menu as the name of the link. If I select one of the Windows special folders, say the Documents folder inside the Libraries folder in Explorer then $s_FileName is returned as  "::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms". To get a display name for the menu item I use the function with the selected folder path.

SpecialFolders_GetSelfName($s_FileName)

This returns a name of the special folder, in this case Documents. This is retrieved from the folder object by using self.name. What I also require is the full path of the folder,

$s_FileName = '::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms'

but the true folder path that I want is

C:\Users\Benners\AppData\Roaming\Microsoft\Windows\Libraries\Documents.library-ms

With the true folder path I can check if it exists on the computer and if not the menu item pointing to this folder will be disabled. I have written some functions here https://www.autoitscript.com/forum/topic/160630-retrieving-known-and-special-folders/?do=findComment&comment=1165814 but I need to know the CSIDL parameter for _WinAPI_ShellGetSpecialFolderPath.

I am sure there must be a property of the Shell.Application object that contains the full path but I haven't been able to work how to get it,

if you run the code below it opens Windows Explorer at the correct window so the path is stored.somewhere

shellexecute('::{031E4825-7B94-4DC3-B131-E946B44C8DD5}\Documents.library-ms')

 

Edited by benners

Share this post


Link to post
Share on other sites

I'm going to rewrite what I read so I understand what you are trying to do:

You want to bring up a folder select dialog. You want to choose a folder from that dialog. When you chose a folder and click chose folder you want the path for that folder to be the full path. You are clicking on the symbolic folders introduced Windows Vista and up. If you click on the symbolic folder you need the full path, not the symbolic path. 

Question. Do you want a file name or just the folder name?


Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Yes. The selected folders maybe virtual types like the Library folders. When the Select Folder button is clicked and the value is added to the $s_FileName variable I want that variable to be a valid path to the folder. It doesn't matter about a file name. The Variable is only $s_FileName because it is also used for a FileSelect dialog box as well.

I have been having a play and this is sort of a workaround. This returns the full path, even if you select a special folder that returns "::{031E" etc

; users chooses a folder
$s_FileName = FileSelectFolder('Please Select The Folder...', '', 3, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
If Not @error Then MsgBox(0,'', Folder_ReturnPath($s_FileName))

Func Folder_ReturnPath($s_Path)
    Local $s_Lnk = @DesktopDir & '\FileName.lnk'

    FileCreateShortcut($s_Path, $s_Lnk)
    Local $a_Shortcut = FileGetShortcut($s_Lnk)

    FileDelete($s_Lnk)

    if IsArray($a_Shortcut) then Return $a_Shortcut[0]
    Return ''
EndFunc

 

Edited by benners

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

If your workaround works then we should stop looking. If there are no problems then you should be good. However, when I add a symbolic link to a folder I get just the name of the folder. For instance the return of:

#include <WinAPIShPath.au3>

; users chooses a folder
$s_FileName = FileSelectFolder('Please Select The Folder...', '', 3, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")

MsgBox(0,'', _WinAPI_PathStripPath($s_FileName))

when I select the documents symbolic link folder the msgbox returns 'Documents'. If I strip away the _WinAPI_PathStripPath then I get the full path to the documents folder. This also works for me in the app data folder. Also I would recommend removing the  "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and just leave it blank. It does not bring up anything relevant on my side when I run the script.

Edited by computergroove

Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Share this post


Link to post
Share on other sites

Yep I'll stick with the workaround and stop looking. that's when I tend to find things ;)

The only ones that I have seen returning this type of string are the ones that are under the libraries group and visible in the navigation pane like in the attached pic. I still think there must be a way to get the path but I have wasted to much time on it so the workaround it is.

Thanks for your time.

Libraries.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now