¿Cuál es la mejor manera de asignar unidades de Windows usando Python?
mapping drive (8)
¿Cuál es la mejor manera de asignar un recurso compartido de red a una unidad de Windows usando Python? Este recurso compartido también requiere un nombre de usuario y contraseña.
Aprovechando la sugerencia de @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)
Prefiero este enfoque simple, especialmente si toda la información es estática.
Aquí hay un par de enlaces que muestran el uso del módulo win32net que debe proporcionar la funcionalidad que necesita.
http://docs.activestate.com/activepython/2.4/pywin32/html/win32/help/win32net.html http://www.blog.pythonlibrary.org/?p=20
Bueno, aquí hay otro método ...
Este fue después de pasar por Win32wnet. Déjame saber lo que piensas...
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
Y para desasignar, solo usa ...
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
Iría con IronPython y este artículo: Mapeo de una letra de unidad programáticamente . O podrías usar la API de Win32 directamente.
No tengo un servidor para probar aquí en casa, pero ¿quizás podría simplemente usar el módulo de subproceso de la biblioteca estándar para ejecutar el comando NET USE apropiado?
Mirando a NET HELP USE desde un indicador de comandos de Windows, parece que debería poder ingresar tanto la contraseña como la identificación del usuario en el comando net use para asignar la unidad.
Una prueba rápida en el intérprete de un comando de uso de net bare sin el material de mapeo:
>>> import subprocess
>>> subprocess.check_call([''net'', ''use''])
New connections will be remembered.
There are no entries in the list.
0
>>>
Si desea asignar el usuario de inicio de sesión actual, creo que el subproceso resuelve su problema. Pero es que desea controlar diferentes asignaciones para diferentes usuarios, desde una sola cuenta maestra. Podrías hacer esto desde el registro de windows.
La idea es cargar el perfil de un usuario determinado.
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)
Suponiendo que importa las bibliotecas necesarias, esto formaba parte de un servidor RPC donde el cliente solicitó al servidor que asigne una unidad localmente ...
#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'',)
================ Compruebe los espacios en blanco desde aquí, estos eran parte de una función ============
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
Tuve problemas para hacer funcionar esta línea:
win32wnet.WNetAddConnection2 (win32netcon.RESOURCETYPE_DISK, unidad, networkPath, Ninguno, usuario, contraseña)
Pero fue exitoso con esto:
win32wnet.WNetAddConnection2 (1, ''Z:'', r ''/ UNCpath / share'', Ninguno, ''inicio de sesión'', ''contraseña'')