2009-08-13 5 views

risposta

2

Non ho un server per testare con qui a casa, ma forse si può semplicemente utilizzare il modulo sottoprocesso della libreria standard per eseguire il comando appropriato NET USE?

Guardando NET HELP USE da un prompt dei comandi di Windows, sembra che sia possibile immettere sia la password che l'id utente nel comando net use per mappare l'unità.

Un test rapido nell'interprete di un comando net use nudo w/o la roba mappatura:

>>> import subprocess 
>>> subprocess.check_call(['net', 'use']) 
New connections will be remembered. 

There are no entries in the list. 

0 
>>> 
2

Supponendo che si importano le librerie necessarie, questa era una parte di un server RPC in cui il cliente ha richiesto la server per mappare un'unità a livello locale ...

#Small function to check the availability of network resource. 
def isAvailable(path): 
    winCMD = 'IF EXIST ' + path + ' echo YES' 
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate() 
    return string.find(str(cmdOutPut), 'YES',) 

#Small function to check if the mention location is a directory 
def isDirectory(path): 
    winCMD = 'dir ' + path + ' | FIND ".."' 
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate() 
    return string.find(str(cmdOutPut), 'DIR',) 

================ Controllare gli spazi bianchi da qui, questi sono stati una parte di una funzione ==== ========

def mapNetworkDrive(self, drive, networkPath, user, password): 

    #Check for drive availability 
    if isAvailable(drive) > -1: 
     #Drive letter is already in use 
     return -1 

    #Check for network resource availability 
    if isAvailable(networkPath) == -1: 
     print "Path not accessible: ", networkPath 
     #Network path is not reachable 
     return -1 

    #Prepare 'NET USE' commands 
    winCMD1 = 'NET USE ' + drive + ' ' + networkPath 
    winCMD2 = winCMD1 + ' ' + password + ' /User' + user 

    print "winCMD1 = ", winCMD1 
    print "winCMD2 = ", winCMD2 
    #Execute 'NET USE' command with authentication 
    winCMD = winCMD2 
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate() 
    print "Executed: ", winCMD 
    if string.find(str(cmdOutPut), 'successfully',) == -1: 
     print winCMD, " FAILED" 
     winCMD = winCMD1 
     #Execute 'NET USE' command without authentication, incase session already open 
     cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate() 
     print "Executed: ", winCMD 
     if string.find(str(cmdOutPut), 'successfully',) == -1: 
      print winCMD, " FAILED" 
      return -1 
     #Mapped on second try 
     return 1 
    #Mapped with first try 
    return 1 

def unmapNetworkDrive(self, drive): 

    #Check if the drive is in use 
    if isAvailable(drive) == -1: 
     #Drive is not in use 
     return -1 

    #Prepare 'NET USE' command 
    winCMD = 'net use ' + drive + ' /DELETE' 
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate() 
    if string.find(str(cmdOutPut), 'successfully',) == -1: 
     #Could not UN-MAP, this might be a physical drive 
     return -1 
    #UN-MAP successful 
    return 1 
6

OK, ecco un altro metodo ...

Questo era dopo aver attraversato win32wnet. Fatemi sapere cosa ne pensate ...

def mapDrive(drive, networkPath, user, password, force=0): 
    print networkPath 
    if (os.path.exists(drive)): 
     print drive, " Drive in use, trying to unmap..." 
     if force: 
      try: 
       win32wnet.WNetCancelConnection2(drive, 1, 1) 
       print drive, "successfully unmapped..." 
      except: 
       print drive, "Unmap failed, This might not be a network drive..." 
       return -1 
     else: 
      print "Non-forcing call. Will not unmap..." 
      return -1 
    else: 
     print drive, " drive is free..." 
    if (os.path.exists(networkPath)): 
     print networkPath, " is found..." 
     print "Trying to map ", networkPath, " on to ", drive, " ....." 
     try: 
      win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, drive, networkPath, None, user, password) 
     except: 
      print "Unexpected error..." 
      return -1 
     print "Mapping successful" 
     return 1 
    else: 
     print "Network path unreachable..." 
     return -1 

E per eliminare la mappatura, basta usare ....

def unmapDrive(drive, force=0): 
    #Check if the drive is in use 
    if (os.path.exists(drive)): 
     print "drive in use, trying to unmap..." 
     if force == 0: 
      print "Executing un-forced call..." 
     try: 
      win32wnet.WNetCancelConnection2(drive, 1, force) 
      print drive, "successfully unmapped..." 
      return 1 
     except: 
      print "Unmap failed, try again..." 
      return -1 
    else: 
     print drive, " Drive is already free..." 
     return -1 
+0

L'utilizzo di 'win32wnet.WNetAddConnection2' e' win32wnet.WNetCancelConnection2' è una buona idea. Ma notare le eccezioni e restituire un codice di ritorno non sembra necessario. Le eccezioni built-in forniscono già buone informazioni sui resi. Inoltre, non è una buona pratica catturare un vuoto 'tranne'. – twasbrillig

17

costruzione fuori del suggerimento di @ Anon:

# Drive letter: M 
# Shared drive path: \\shared\folder 
# Username: user123 
# Password: password 
import subprocess 

# Disconnect anything on M 
subprocess.call(r'net use m: /del', shell=True) 

# Connect to shared drive, use drive letter M 
subprocess.call(r'net use m: \\shared\folder /user:user123 password', shell=True) 

preferisco questo approccio semplice, soprattutto se tutte le informazioni sono statiche.

+0

Ho una domanda su questa configurazione. Quando si tenta di mappare l'unità in un'app Web, l'unità è mappata all'utente che sta eseguendo l'app o il server? – wolf97084

+1

Usa 'net use a:/del/Y' per forzare, altrimenti si bloccherà chiedendo conferma per eliminare – Tahlor

+0

Anche se facciamo 'net use *' + "\\ UNC path \ folder" troverà automaticamente un vuoto slot drive per montare "UNC \ path \ folder" – Dylan

0

ho avuto difficoltà a raggiungere questa linea di lavoro:

win32wnet.WNetAddConnection2 (win32netcon.RESOURCETYPE_DISK, unità, NetworkPath, None, utente, password)

Ma ha avuto successo con questo:

win32wnet .WNetAddConnection2 (1, 'Z:', r '\ UNCpath \ share', None, 'login', 'password')

0

Se si desidera mappare l'utente di accesso corrente, penso che il sottoprocesso risolva il problema. Ma vuoi controllare diversi mapping per utenti diversi, da un singolo account principale. Puoi farlo dal registro di windows

L'idea è di caricare il profilo di un determinato utente.

import win32api 
import win32security 
import win32profile 
import win32netcon 
import win32net 
import win32netcon 
import win32con 

il = 'G' 
m = '\\\\192.168.1.16\\my_share_folder' 
usu = 'my_user' 
cla = 'passwd' 

#login the user 
hUser = win32security.LogonUser(
     usu, 
     None, 
     cla, 
     win32security.LOGON32_LOGON_NETWORK, 
     win32security.LOGON32_PROVIDER_DEFAULT 
    ) 

#load the profile 
hReg = win32profile.LoadUserProfile (
      hUser, 
      {"UserName" : usu} 
      ) 

#alter the regedit entries of usu 
win32api.RegCreateKey(hReg, "Network") 
hkey = win32api.RegOpenKey(hReg, "Network\\", 0, win32con.KEY_ALL_ACCESS) 
win32api.RegCreateKey(hkey, il) 
hkey = win32api.RegOpenKey(hReg, "Network\\%s" % il, 0, win32con.KEY_ALL_ACCESS) 
win32api.RegSetValueEx(hkey, "ConnectionType", 0, win32con.REG_DWORD, 1) 
win32api.RegSetValueEx(hkey, "DeferFlags", 0, win32con.REG_DWORD, 4) 
win32api.RegSetValueEx(hkey, "ProviderName", 0, win32con.REG_SZ, "Red de Microsoft Windows") 
win32api.RegSetValueEx(hkey, "ProviderType", 0, win32con.REG_DWORD, 131072) 
win32api.RegSetValueEx(hkey, "RemotePath", 0, win32con.REG_SZ, m) 
win32api.RegSetValueEx(hkey, "UserName", 0, win32con.REG_DWORD, 0)