2015-04-27 4 views
1

Каков наилучший метод определения пути Windows и в python?Windows Специальные и известные папки из python (меню «Пуск», «Загрузки», ...)

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

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

  • Find system folder locations in Python - простейший метод CSIDL, опирается на win32com, хорошо для AllUsersDesktop, AllUsersStartMenu, AllUsersPrograms, AllUsersStartup, рабочий стол, Избранное, Шрифты, MyDocuments, NetHood, PrintHood, новое , SendTo, StartMenu, Startup & Шаблоны (список, вероятно, неполный).

  • How to get path of Start Menu's Programs directory? - имеет такой же подход, что и выше, а также метод с использованием ctypes непосредственно, так win32com не требуется (не ясно, или просто)

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

  • ?

И в одном

  • ?
+0

Википедия имеет их список в ** http: //en.wikipedia.org/wiki/Special_folder#List_of_special_folders** – Marichyasana

+0

Спасибо @Marichyasana, но мне нужно определить, что они динамически во время выполнения. Они не всегда имеют одинаковые варианты написания (разные языки) и могут находиться в разных местах в соответствии с групповой политикой и/или другими настройками. Этот список википедии также очень неполный. –

ответ

2

Вы решаете эту проблему так же, как и ее: сначала вы найдете документацию и, в идеале, хороший код примера на C++, C# или VB, то вы выясните, как использовать PyWin32 для создания того же API-интерфейса оболочки или IKnownFolder COM-вызовы с Python.

Как обзор документации MSDN по Known Folders говорит, вы можете использовать новую функцию оболочки обертку 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 it was added in build 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 
+0

Ваша интуиция верна, win32com.shell не имеет функции SHGetKnownFolderPath, по крайней мере, не на моей машине Win7 py27. Инициирование IKnownFolderManager через COM выходит за рамки моего понимания. В конце концов я отследил ваш ключ к 'shell.IID_IKnownFolderManagement' (спасибо, я использовал более старый pywin32 без него), но атрибут GetFolderByName не существует. «Чистый поиск не привел примеры, просто объявление о его доступности. Я нашел такие элементы, как 'shell.FOLDERID_Downloads', которые возвращают код IID, но я не смог выяснить, как использовать это для перехода к пути. –

+0

Признаюсь в недоумении. Windows KnownFolders давно отсутствовали, и я ожидал, что вас укажет на хорошо проторенный путь. Наверное, я испорчен, потому что большинство моих квестов на python на сегодняшний день относятся к сорту батарей. :) ... Я рассмотрю пример ctypes завтра. Может быть, это принесет мне больше плода. (Почти забыл: большое спасибо за то, что дал мне что-то, что можно было перерыть и пережевать.) –

+0

Вспомнил, что вчера наткнулся на этот пример ctypes, https://gist.github.com/mkropat/7550097. Он похож на ваш, хотя мне еще предстоит изучить его внимательно, чтобы увидеть, является ли сходство только поверхностным. В моем быстром первоначальном тестировании он всегда возвращает значения для значения по умолчанию вместо текущего пользователя. –