Qual è il modo migliore per mappare una condivisione di rete su un'unità Windows utilizzando Python? Questa condivisione richiede anche un nome utente e una password.Qual è il modo migliore per mappare le unità Windows utilizzando Python?
risposta
Vorrei andare con IronPython e questo articolo: Mapping a Drive Letter Programmatically. O potresti usare direttamente l'API Win32.
Di seguito sono riportati alcuni collegamenti che mostrano l'utilizzo del modulo win32net che dovrebbe fornire le funzionalità necessarie.
http://docs.activestate.com/activepython/2.4/pywin32/html/win32/help/win32net.html http://www.blog.pythonlibrary.org/?p=20
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
>>>
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
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
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.
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
Usa 'net use a:/del/Y' per forzare, altrimenti si bloccherà chiedendo conferma per eliminare – Tahlor
Anche se facciamo 'net use *' + "\\ UNC path \ folder" troverà automaticamente un vuoto slot drive per montare "UNC \ path \ folder" – Dylan
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')
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)
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