2016-03-07 17 views
7

Tôi đã tìm thấy this question gợi ý sử dụng os.path.expanduser(path) để nhận thư mục chính của người dùng.python - Tìm thư mục "Tải xuống" của người dùng

Tôi muốn đạt được điều tương tự với thư mục "Tải xuống". Tôi biết rằng this is possible in C#, nhưng tôi mới với Python và không biết nếu điều này là có thể ở đây quá, thích hợp hơn nền tảng độc lập (Windows, Ubuntu).

Tôi biết rằng tôi chỉ có thể làm download_folder = os.path.expanduser("~")+"/Downloads/", nhưng (at least in Windows) it is possible to change the Default download folder.

+2

Với đủ ctypes-foo bạn có thể điều chỉnh [mã dành riêng cho Windows trong câu trả lời này] (http://stackoverflow.com/a/7672816/1600898) thành Python (với một dự phòng cho 'os.expanduser (...)' trên các nền tảng không phải Windows). [Ở đây] (http://stackoverflow.com/a/29888752/1600898) là một ví dụ. Tuy nhiên, lưu ý rằng thư mục "Tải xuống" không phải là khái niệm độc lập nền tảng. Có thể gặp phải các hệ thống Linux không có, vì vậy hãy chắc chắn tạo ra nó nếu nó không tồn tại. – user4815162342

+0

@ user4815162342: Ok, cảm ơn lời khuyên với thư mục 'a' Tải xuống 'không phải là khái niệm độc lập nền tảng.'! –

Trả lời

5

Định vị chính xác các thư mục Windows có phần là một việc vặt trong Python. Theo câu trả lời bao gồm các công nghệ phát triển của Microsoft, chẳng hạn như this one, chúng phải được lấy bằng cách sử dụng Vista Known Folder API. API này không được bao bọc bởi thư viện chuẩn Python (mặc dù có an issue from 2008 yêu cầu nó), nhưng có thể sử dụng mô-đun ctypes để truy cập nó.

Thích ứng với câu trả lời trên để sử dụng id thư mục để tải shown here và kết hợp nó với mã Unix hiện tại của bạn nên kết quả trong mã mà trông như thế này:

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") 

Một module hoàn chỉnh hơn để lấy các thư mục được biết đến từ Python là available on github.

+0

Cảm ơn bạn đã điều tra chi tiết và liên kết đến vấn đề này. –

+1

@MarkusWeninger Bạn cũng có thể muốn xem [trình bao bọc hoàn chỉnh hơn này] (https://gist.github.com/mkropat/7550097) cho 'SHGetKnownFolderPath'. – user4815162342

+0

Cảm ơn! Tôi sẽ nhìn vào nó. 'get_download_folder()' hiện đang treo với lỗi sau. 'File". \ Downloadfolders.py ", dòng 34, trong _get_known_folder_path nếu SHGetKnownFolderPath (ctypes.byref (guid), 0, 0, ctypes.byref (pathptr)): ctypes.ArgumentError: đối số 4: : trường hợp LP_c_char_p được mong đợi thay vì trỏ tới c_wchar_p' –

2

giải pháp khá đơn giản này (mở rộng từ this reddit bưu điện) làm việc cho tôi

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') 
  • Các GUID thể được lấy từ Microsoft KNOWNFOLDERID docs
  • này có thể được mở rộng để làm việc quát nhiều thư mục khác
Các vấn đề liên quan