2018-08-08 15:30:41 +02:00
|
|
|
"""
|
|
|
|
System File Locations
|
|
|
|
Retrieves common system path names on Windows XP/Vista
|
|
|
|
Depends only on ctypes, and retrieves path locations in Unicode
|
|
|
|
"""
|
|
|
|
|
|
|
|
import ctypes
|
2019-12-20 10:19:03 +01:00
|
|
|
from ctypes import windll, wintypes # type: ignore
|
2018-08-08 15:30:41 +02:00
|
|
|
|
|
|
|
__license__ = "MIT"
|
|
|
|
__version__ = "0.2"
|
|
|
|
__author__ = "Ryan Ginstrom"
|
|
|
|
__description__ = "Retrieves common Windows system paths as Unicode strings"
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2021-10-03 10:59:42 +02:00
|
|
|
class PathConstants:
|
2018-08-08 15:30:41 +02:00
|
|
|
"""
|
|
|
|
Define constants here to avoid dependency on shellcon.
|
|
|
|
Put it in a class to avoid polluting namespace
|
|
|
|
"""
|
|
|
|
|
|
|
|
CSIDL_DESKTOP = 0
|
|
|
|
CSIDL_PROGRAMS = 2
|
|
|
|
CSIDL_PERSONAL = 5
|
|
|
|
CSIDL_FAVORITES = 6
|
|
|
|
CSIDL_STARTUP = 7
|
|
|
|
CSIDL_RECENT = 8
|
|
|
|
CSIDL_SENDTO = 9
|
|
|
|
CSIDL_BITBUCKET = 10
|
|
|
|
CSIDL_STARTMENU = 11
|
|
|
|
CSIDL_MYDOCUMENTS = 12
|
|
|
|
CSIDL_MYMUSIC = 13
|
|
|
|
CSIDL_MYVIDEO = 14
|
|
|
|
CSIDL_DESKTOPDIRECTORY = 16
|
|
|
|
CSIDL_DRIVES = 17
|
|
|
|
CSIDL_NETWORK = 18
|
|
|
|
CSIDL_NETHOOD = 19
|
|
|
|
CSIDL_FONTS = 20
|
|
|
|
CSIDL_TEMPLATES = 21
|
|
|
|
CSIDL_COMMON_STARTMENU = 22
|
|
|
|
CSIDL_COMMON_PROGRAMS = 23
|
|
|
|
CSIDL_COMMON_STARTUP = 24
|
|
|
|
CSIDL_COMMON_DESKTOPDIRECTORY = 25
|
|
|
|
CSIDL_APPDATA = 26
|
|
|
|
CSIDL_PRINTHOOD = 27
|
|
|
|
CSIDL_LOCAL_APPDATA = 28
|
|
|
|
CSIDL_ALTSTARTUP = 29
|
|
|
|
CSIDL_COMMON_ALTSTARTUP = 30
|
|
|
|
CSIDL_COMMON_FAVORITES = 31
|
|
|
|
CSIDL_INTERNET_CACHE = 32
|
|
|
|
CSIDL_COOKIES = 33
|
|
|
|
CSIDL_HISTORY = 34
|
|
|
|
CSIDL_COMMON_APPDATA = 35
|
|
|
|
CSIDL_WINDOWS = 36
|
|
|
|
CSIDL_SYSTEM = 37
|
|
|
|
CSIDL_PROGRAM_FILES = 38
|
|
|
|
CSIDL_MYPICTURES = 39
|
|
|
|
CSIDL_PROFILE = 40
|
|
|
|
CSIDL_SYSTEMX86 = 41
|
|
|
|
CSIDL_PROGRAM_FILESX86 = 42
|
|
|
|
CSIDL_PROGRAM_FILES_COMMON = 43
|
|
|
|
CSIDL_PROGRAM_FILES_COMMONX86 = 44
|
|
|
|
CSIDL_COMMON_TEMPLATES = 45
|
|
|
|
CSIDL_COMMON_DOCUMENTS = 46
|
|
|
|
CSIDL_COMMON_ADMINTOOLS = 47
|
2019-12-23 01:34:10 +01:00
|
|
|
CSIDL_ADMINTOOLS = 48
|
2018-08-08 15:30:41 +02:00
|
|
|
CSIDL_CONNECTIONS = 49
|
|
|
|
CSIDL_COMMON_MUSIC = 53
|
|
|
|
CSIDL_COMMON_PICTURES = 54
|
|
|
|
CSIDL_COMMON_VIDEO = 55
|
|
|
|
CSIDL_RESOURCES = 56
|
|
|
|
CSIDL_RESOURCES_LOCALIZED = 57
|
|
|
|
CSIDL_COMMON_OEM_LINKS = 58
|
|
|
|
CSIDL_CDBURN_AREA = 59
|
|
|
|
# 60 unused
|
|
|
|
CSIDL_COMPUTERSNEARME = 61
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
class WinPathsException(Exception):
|
|
|
|
pass
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def _err_unless_zero(result):
|
|
|
|
if result == 0:
|
|
|
|
return result
|
|
|
|
else:
|
2021-02-11 01:09:06 +01:00
|
|
|
raise WinPathsException(f"Failed to retrieve windows path: {result}")
|
2018-08-08 15:30:41 +02:00
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
_SHGetFolderPath = windll.shell32.SHGetFolderPathW
|
2019-12-23 01:34:10 +01:00
|
|
|
_SHGetFolderPath.argtypes = [
|
|
|
|
wintypes.HWND,
|
|
|
|
ctypes.c_int,
|
|
|
|
wintypes.HANDLE,
|
|
|
|
wintypes.DWORD,
|
|
|
|
wintypes.LPCWSTR,
|
|
|
|
]
|
2018-08-08 15:30:41 +02:00
|
|
|
_SHGetFolderPath.restype = _err_unless_zero
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def _get_path_buf(csidl):
|
2018-08-08 15:31:18 +02:00
|
|
|
path_buf = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
|
2018-08-08 15:30:41 +02:00
|
|
|
result = _SHGetFolderPath(0, csidl, 0, 0, path_buf)
|
|
|
|
return path_buf.value
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_local_appdata():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_LOCAL_APPDATA)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_appdata():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_APPDATA)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_desktop():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_DESKTOP)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_programs():
|
|
|
|
"""current user -> Start menu -> Programs"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_PROGRAMS)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_admin_tools():
|
|
|
|
"""current user -> Start menu -> Programs -> Admin tools"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_ADMINTOOLS)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_common_admin_tools():
|
|
|
|
"""all users -> Start menu -> Programs -> Admin tools"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_COMMON_ADMINTOOLS)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_common_appdata():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_COMMON_APPDATA)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_common_documents():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_COMMON_DOCUMENTS)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_cookies():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_COOKIES)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_history():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_HISTORY)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_internet_cache():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_INTERNET_CACHE)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_my_pictures():
|
|
|
|
"""Get the user's My Pictures folder"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_MYPICTURES)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_personal():
|
|
|
|
"""AKA 'My Documents'"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_PERSONAL)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
get_my_documents = get_personal
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_program_files():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_PROGRAM_FILES)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_program_files_common():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_PROGRAM_FILES_COMMON)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_system():
|
|
|
|
"""Use with care and discretion"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_SYSTEM)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_windows():
|
|
|
|
"""Use with care and discretion"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_WINDOWS)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_favorites():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_FAVORITES)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_startup():
|
|
|
|
"""current user -> start menu -> programs -> startup"""
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_STARTUP)
|
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2018-08-08 15:30:41 +02:00
|
|
|
def get_recent():
|
|
|
|
return _get_path_buf(PathConstants.CSIDL_RECENT)
|