Skip to content

Instantly share code, notes, and snippets.

@pmslavin
Last active October 31, 2024 20:14
Show Gist options
  • Select an option

  • Save pmslavin/dbcfeb860aa22db0ca022cf1a9b0f1c4 to your computer and use it in GitHub Desktop.

Select an option

Save pmslavin/dbcfeb860aa22db0ca022cf1a9b0f1c4 to your computer and use it in GitHub Desktop.
Python example of locating the Common Documents path on Windows using either the legacy CSIDL or Known Public Folder systems
import ctypes
import uuid
from ctypes import (
windll,
wintypes
)
# Pre-Vista CSIDL
CSIDL_COMMON_DOCUMENTS = 46
# Vista onwards Known Folder ID
# From https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid
KFP_PUBLIC_DOCUMENTS = uuid.UUID("{ED4824AF-DCE4-45A8-81E2-FC7965083634}")
class GUID(ctypes.Structure):
# windsdk/guiddef.h
_fields_ = [
("Data1", wintypes.DWORD),
("Data2", wintypes.WORD),
("Data3", wintypes.WORD),
("Data4", wintypes.BYTE*8)
]
def __init__(self, _uuid):
ctypes.Structure.__init__(self)
self.Data1, self.Data2, self.Data3 = _uuid.fields[:3]
self.Data4[:] = _uuid.bytes[8:]
def check_ret_err(result, func, args):
if result != 0:
raise OSerror("Unable to locate Common Documents")
return args
def win_get_common_documents():
# If the more recent KPF system is available, use this...
if Win_SHGetKnownFolderPath := getattr(windll.shell32, "SHGetKnownFolderPath", None):
Win_SHGetKnownFolderPath.argtypes = [
ctypes.POINTER(GUID),
wintypes.DWORD,
wintypes.HANDLE,
ctypes.POINTER(ctypes.c_wchar_p)
]
Win_SHGetKnownFolderPath.errcheck = check_ret_err
kfp = GUID(KFP_PUBLIC_DOCUMENTS)
path_buf = ctypes.c_wchar_p()
Win_SHGetKnownFolderPath(ctypes.byref(kfp), 0, 0, ctypes.byref(path_buf))
return path_buf.value
# ...otherwise use legacy CSIDL
elif Win_SHGetFolderPathW := getattr(windll.shell32, "SHGetFolderPathW", None):
Win_SHGetFolderPathW.argtypes = [
wintypes.HWND,
ctypes.c_int,
wintypes.HANDLE,
wintypes.DWORD,
wintypes.LPCWSTR
]
Win_SHGetFolderPathW.errcheck = check_ret_err
path_buf = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
Win_SHGetFolderPathW(0, CSIDL_COMMON_DOCUMENTS, 0, 0, path_buf)
return path_buf.value
else:
raise OSError("Unable to access Windows environment")
if __name__ == "__main__":
cdp = win_get_common_documents()
print(cdp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment