2010-04-12 13 views

risposta

9

mi piacerebbe provare a mappare la condivisione a una lettera di unità inutilizzata chiamando il comando NET USE utilizzando os.system (supponendo che siete su Windows):

os.system(r"NET USE P: \\ComputerName\ShareName %s /USER:%s\%s" % (password, domain_name, user_name)) 

Dopo aver mappato la condivisione a una lettera di unità, è possibile utilizzare shutil.copyfile per copiare il file nell'unità specificata. Infine, è necessario smontare la condivisione:

os.system(r"NET USE P: /DELETE") 

Naturalmente questo funziona solo su Windows, e si dovrà fare in modo che la lettera di unità P è disponibile. È possibile controllare il codice di ritorno del comando NET USE per verificare se il montaggio è riuscito; in caso contrario, puoi provare una lettera di unità diversa fino a quando non ci riesci.

Poiché i due comandi NET USE sono in coppia e il secondo deve essere sempre eseguito quando è stato eseguito il primo (anche se è stata sollevata un'eccezione nel mezzo), è possibile eseguire il wrap di queste due chiamate in un gestore di contesto se si stanno usando Python 2.5 o successiva:

from contextlib import contextmanager 

@contextmanager 
def network_share_auth(share, username=None, password=None, drive_letter='P'): 
    """Context manager that mounts the given share using the given 
    username and password to the given drive letter when entering 
    the context and unmounts it when exiting.""" 
    cmd_parts = ["NET USE %s: %s" % (drive_letter, share)] 
    if password: 
     cmd_parts.append(password) 
    if username: 
     cmd_parts.append("/USER:%s" % username) 
    os.system(" ".join(cmd_parts)) 
    try: 
     yield 
    finally: 
     os.system("NET USE %s: /DELETE" % drive_letter) 

with network_share_auth(r"\\ComputerName\ShareName", username, password): 
    shutil.copyfile("foo.txt", r"P:\foo.txt") 
+0

Ciao qual è l'argomento del nome di dominio? – user218976

+0

L'argomento nome doomain può essere utilizzato quando l'utente autenticato si trova in un dominio di autenticazione diverso. Non l'ho incluso nella versione contextlib perché può semplicemente essere parte del nome utente. Se l'utente che si autentica si trova nello stesso dominio dell'utente corrente, il dominio può essere omesso. –

+0

Grazie ... ha funzionato ... solo a volte se lo eseguo una seconda volta ottengo un errore che dice che il dispositivo locale è in uso. – user218976

2

Se avete la libreria pywin32 (ad esempio, arriva parte della distro ActiveState Python), allora si può ottenere fatto in poche righe, senza mappare un'unità:

import win32wnet 
win32wnet.WNetAddConnection2(0, None, '\\\\'+host, None, username, password) 
shutil.copy(source_file, '\\\\'+host+dest_share_path+'\\') 
win32wnet.WNetCancelConnection2('\\\\'+host, 0, 0) # optional disconnect 

C'è a more complete example on ActiveState Code

Problemi correlati