Специальные и известные папки Windows из python (меню Пуск, Загрузка, ...)
Каков наилучший способ определения пути специальных папок Windows и известных папок в Python?
Я обнаружил пару популярных методов для SpecialFolders, также называемых CSIDL, но пока ничего не известно для KNOWNFOLDERID. Поддерживается обратная совместимость, поэтому методы CSIDL по-прежнему работают, но любые специальные / известные папки, введенные после Windows XP, там не перечислены. Примеры "новых" недоступных включают " Загрузки", "Плейлисты", "Program Files x64".
Специальные папки
Найти расположение системных папок в Python - самый простой метод CSIDL, опирается на win32com, подходит для AllUsersDesktop, AllUsersStartMenu, AllUsersPrograms, AllUsersStartup, рабочего стола, избранного, шрифтов, MyDocuments, NetHood, PrintHood, Recent, SendTo, StartMenu, Startup & Templates (список, вероятно, неполный)).
Как получить путь к каталогу программ меню "Пуск"? - имеет тот же подход, что и выше, а также метод, использующий ctypes напрямую, поэтому win32com не нужен (не так ясно или просто)
Известные папки
- ?
Оба в одном
- ?
1 ответ
Вы решаете эту проблему так же, как и этот: сначала вы найдете документацию и в идеале хороший пример кода на C++, C# или VB, а затем выясните, как использовать PyWin32 для создания того же API-интерфейса оболочки или IKnownFolder
COM звонки из Python.
Как говорится в обзорной документации MSDN об известных папках, вы можете использовать новую функцию оболочки оболочки SHGetKnownFolderPath
вместо старого SHFolderPath
или же SHGetFolderPath
, или вы можете использовать полный IKnownFolderManager
интерфейс через COM.
К сожалению, передо мной нет машины с Windows, и примеры загрузки MSDN не отвечают, поэтому мне придется немного угадать. Но это может быть что-то вроде этого:
from win32com.shell import shell, shellcon
path = shell.SHGetKnownFolderPath(shellcon.FOLDERID_AccountPictures,
0, # see KNOWN_FOLDER_FLAG
0) # current user
Если shellcon
не имеет FOLDERID
ценности, вам придется искать их на KNOWNFOLDERID
и определите нужные вам константы.
Если shell
не имеет SHGetKnownFolderPath
функция, вам придется создать экземпляр IKnownFolderManager
и позвонить GetFolderByName
,
Если shell
даже не имеет IKnownFolderManager
… Но быстрый Google показывает, что он был добавлен в сборку 218, так что это не будет проблемой.
Если вы хотите сделать это через ctypes
чем win32com
, это будет выглядеть примерно так (опять же, не проверено, потому что у меня нет окна Windows и сервер MSDN не работает):
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