2016-03-07 25 views
7

Ho già trovato this question che suggerisce di utilizzare os.path.expanduser(path) per ottenere la directory home dell'utente.python - Ricerca della cartella "Download" dell'utente

Mi piacerebbe ottenere lo stesso con la cartella "Download". So che è this is possible in C#, eppure sono nuovo di Python e non so se questo è possibile anche qui, preferibile indipendentemente dalla piattaforma (Windows, Ubuntu).

So che potrei fare solo download_folder = os.path.expanduser("~")+"/Downloads/", ancora (at least in Windows) it is possible to change the Default download folder.

+2

Con sufficiente ctype-foo è possibile adattare [il codice specifico di Windows in questa risposta] (http://stackoverflow.com/a/7672816/1600898) a Python (con un fallback a 'os.expanduser (...)' su piattaforme non Windows). [Qui] (http://stackoverflow.com/a/29888752/1600898) è un esempio. Si noti, tuttavia, che una directory "Download" non è un concetto indipendente dalla piattaforma. È abbastanza possibile incontrare sistemi Linux che non ne hanno uno, quindi assicurati di crearlo se non esiste. – user4815162342

+0

@ user4815162342: Ok, grazie per il consiglio con una directory "Download" non è un concetto indipendente dalla piattaforma.! –

risposta

5

Posizionare correttamente le cartelle di Windows è un po 'un lavoro di routine in Python. In base alle risposte relative alle tecnologie di sviluppo Microsoft, ad esempio this one, è necessario ottenerle utilizzando Vista Known Folder API. Questa API non è racchiusa dalla libreria standard Python (sebbene ci sia an issue from 2008 che la richiede), ma si può usare il modulo ctypes per accedervi comunque.

adattamento della risposta di cui sopra utilizzare l'ID della cartella per i download shown here e combinandolo con il codice UNIX esistente dovrebbe risultare in codice che assomiglia a questo:

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

Un modulo più completa per il recupero di cartelle noti da Python è available on github.

+0

Grazie per l'indagine dettagliata e il link al problema. –

+1

@MarkusWeninger Potresti anche dare un'occhiata a [questo wrapper più completo] (https://gist.github.com/mkropat/7550097) per 'SHGetKnownFolderPath'. – user4815162342

+0

Grazie! Lo esaminerò. 'get_download_folder()' attualmente si blocca con il seguente errore. 'File". \ Downloadfolders.py ", riga 34, in _get_known_folder_path se SHGetKnownFolderPath (ctypes.byref (guid), 0, 0, ctypes.byref (pathptr)): ctypes.ArgumentError: argomento 4: : istanza LP_c_char_p prevista anziché puntatore a c_wchar_p' –

2

questa abbastanza semplice soluzione (ampliato da this posta reddit) ha lavorato per me

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') 
  • Il GUID può essere ottenuto da Microsoft di KNOWNFOLDERID docs
  • Questo può essere ampliato a lavorare più genericamente altre directory