Специальные и известные папки Windows из python (меню Пуск, Загрузка, ...)

Каков наилучший способ определения пути специальных папок Windows и известных папок в Python?

Я обнаружил пару популярных методов для SpecialFolders, также называемых CSIDL, но пока ничего не известно для KNOWNFOLDERID. Поддерживается обратная совместимость, поэтому методы CSIDL по-прежнему работают, но любые специальные / известные папки, введенные после Windows XP, там не перечислены. Примеры "новых" недоступных включают " Загрузки", "Плейлисты", "Program Files x64".

Специальные папки

Известные папки

  • ?

Оба в одном

  • ?

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
Другие вопросы по тегам