2016-03-07 4 views
7

Я уже нашел this question, который предлагает использовать os.path.expanduser(path), чтобы получить домашний каталог пользователя.python - Поиск папки «Загрузки» пользователя

Я хотел бы добиться того же, что и в папке «Загрузки». Я знаю, что this is possible in C#, но я новичок в Python и не знаю, возможно ли это здесь, предпочтительная платформа-независимая (Windows, Ubuntu).

Я знаю, что я только мог сделать download_folder = os.path.expanduser("~")+"/Downloads/", но (at least in Windows) it is possible to change the Default download folder.

+2

С достаточным количеством ctypes-foo вы можете адаптировать [код для Windows в этом ответе] (http://stackoverflow.com/a/7672816/1600898) к Python (с резерв на 'os.expanduser (...)' на платформах, отличных от Windows). [Здесь] (http://stackoverflow.com/a/29888752/1600898) является примером. Обратите внимание, однако, что каталог «Загрузки» не является платформенно-независимой концепцией. Вполне возможно встретить Linux-системы, у которых их нет, поэтому не забудьте создать их, если они не существуют. – user4815162342

+0

@ user4815162342: Хорошо, спасибо за совет с каталогом 'a« Downloads »не является платформо-независимой концепцией.'! –

ответ

5

Правильное размещение папок Windows является чем-то вроде обычной работы на Python. Согласно ответам, касающимся технологий разработки Microsoft, таких как this one, они должны быть получены с использованием Vista Known Folder API. Этот API не обернут стандартной библиотекой Python (хотя есть an issue from 2008 с запросом), но в любом случае можно использовать модуль ctypes для доступа к нему.

Адаптирование ответа выше, чтобы использовать идентификатор папки для загрузки shown here и комбинируя его с существующим кодом Unix должен привести код, который выглядит следующим образом:

import os 

if os.name == 'nt': 
    import ctypes 
    from ctypes import windll, wintypes 
    from uuid import UUID 

    # ctypes GUID copied from MSDN sample code 
    class GUID(ctypes.Structure): 
     _fields_ = [ 
      ("Data1", wintypes.DWORD), 
      ("Data2", wintypes.WORD), 
      ("Data3", wintypes.WORD), 
      ("Data4", wintypes.BYTE * 8) 
     ] 

     def __init__(self, uuidstr): 
      uuid = UUID(uuidstr) 
      ctypes.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 

    SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath 
    SHGetKnownFolderPath.argtypes = [ 
     ctypes.POINTER(GUID), wintypes.DWORD, 
     wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p) 
    ] 

    def _get_known_folder_path(uuidstr): 
     pathptr = ctypes.c_wchar_p() 
     guid = GUID(uuidstr) 
     if SHGetKnownFolderPath(ctypes.byref(guid), 0, 0, ctypes.byref(pathptr)): 
      raise ctypes.WinError() 
     return pathptr.value 

    FOLDERID_Download = '{374DE290-123F-4565-9164-39C4925E467B}' 

    def get_download_folder(): 
     return _get_known_folder_path(FOLDERID_Download) 
else: 
    def get_download_folder(): 
     home = os.path.expanduser("~") 
     return os.path.join(home, "Downloads") 

Более полный модуль для извлечения известных папок из Python есть available on github.

+0

Спасибо за подробное исследование и ссылку на эту проблему. –

+1

@MarkusWeninger Вы также можете посмотреть [эту более полную обертку] (https://gist.github.com/mkropat/7550097) для 'SHGetKnownFolderPath'. – user4815162342

+0

Спасибо! Я буду смотреть в него. 'get_download_folder()' в настоящее время сбой со следующей ошибкой. 'Файл '. \ Downloadfolders.py", строка 34, в _get_known_folder_path , если SHGetKnownFolderPath (ctypes.byref (guid), 0, 0, ctypes.byref (pathptr)): ctypes.ArgumentError: аргумент 4: <класс' TypeError '>: ожидаемый экземпляр LP_c_char_p вместо указателя на c_wchar_p' –

2

Это довольно простое решение (вспененный из this Reddit пост) работал для меня

import os 

def get_download_path(): 
    """Returns the default downloads path for linux or windows""" 
    if os.name == 'nt': 
     import winreg 
     sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' 
     downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}' 
     with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key: 
      location = winreg.QueryValueEx(key, downloads_guid)[0] 
     return location 
    else: 
     return os.path.join(os.path.expanduser('~'), 'downloads') 
  • идентификатор GUID может быть получен из компании Microsoft KNOWNFOLDERID docs
  • Это может быть расширена, чтобы работать более обобщенно другие каталоги

 Смежные вопросы

  • Нет связанных вопросов^_^