Windows Special and famous folders from python (Start menu, Downloads, ...)

What is the best way to determine the path of Windows special-folders and known-folders to python?

I have uncovered some popular methods for SpecialFolders, aka CSIDL , but nothing simple for KNOWNFOLDERID yet . Support for backward compatibility is maintained, so CSIDL methods still work, but any special / known folders introduced with Windows XP are not listed there. Examples of "new" inaccessibles are: downloads, playlists, x64 program files.

Special folders

  • Finding the location of system folders in Python is the easiest CSIDL method, relies on win32com, good for AllUsersDesktop, AllUsersStartMenu, AllUsersPrograms, AllUsersStartup, Desktop, Favorites, Fonts, MyDocuments, NetHood, PrintHood, Recent, SendTo, StartMenu, Startup and Templates (list probably incomplete).

  • How to get the path to the Start menu program directory? - has the same approach as above, as well as a method that uses ctypes directly, so win32com is not needed (not so clear or simple)

Known Folders

Both in one

+1
python special-folders known-folders
source share
1 answer

You solve this problem in the same way as it: first you will find documentation and, ideally, good example code in C ++, C # or VB, then you will find out how to use PyWin32 to create the same shell API or IKnownFolder COM calls from Python.

As the MSDN overview documentation on Known Folders shows, you can use the new SHGetKnownFolderPath shell instead of the old SHFolderPath or SHGetFolderPath , or you can use the full IKnownFolderManager through COM.

Unfortunately, I do not have a Windows machine in front of me, and downloading MSDN samples does not respond, so I have to guess a little. But it could be something like this:

 from win32com.shell import shell, shellcon path = shell.SHGetKnownFolderPath(shellcon.FOLDERID_AccountPictures, 0, # see KNOWN_FOLDER_FLAG 0) # current user 

If the shellcon does not have FOLDERID values, you will have to look for them on KNOWNFOLDERID and determine the constants you need.

If the shell does not have the SHGetKnownFolderPath function, you need to instantiate IKnownFolderManager and call GetFolderByName .

If the shell doesn't even have an IKnownFolderManager ... but a quick google shows it was added in build 218 , so that won't be a problem.


If you prefer to do this via ctypes than win32com , it will look something like this (again, unverified, because I do not have a Windows window, and the MSDN server is not working):

 from ctypes import windll, wintypes from ctypes import * from uuid import UUID # ctypes GUID copied from MSDN sample code class GUID(Structure): _fields_ = [ ("Data1", wintypes.DWORD), ("Data2", wintypes.WORD), ("Data3", wintypes.WORD), ("Data4", wintypes.BYTE * 8) ] def __init__(self, uuidstr): uuid = UUID(uuidstr) Structure.__init__(self) self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid.fields for i in range(2, 8): self.Data4[i] = rest>>(8-i-1)*8 & 0xff FOLDERID_AccountPictures = '{008ca0b1-55b4-4c56-b8a8-4de4b299d3be}' SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath SHGetKnownFolderPath.argtypes = [ POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, POINTER(c_char_p)] def get_known_folder_path(uuidstr): pathptr = c_wchar_p() guid = GUID(uuidstr) if SHGetKnownFolderPath(byref(guid), 0, 0, byref(pathptr)): raise Exception('Whatever you want here...') return pathptr.value 
+2
source share

All Articles