Каков наилучший способ сопоставления дисков windows с помощью Python?

Как лучше всего сопоставить сетевой ресурс с диском windows с помощью Python? Эта доля также требует имя пользователя и пароль.

8 ответов


Я бы пошел с IronPython и этой статьей:сопоставление буквы диска программно. Или вы можете использовать Win32 API напрямую.


построение из предложения @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)

Я предпочитаю этот простой подход, особенно если вся информация является статической.


хорошо, вот еще один метод...

Это было после прохождения win32wnet. Дай мне знать, что ты думаешь...

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

и unmap, просто используйте....

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

вот несколько ссылок, которые показывают использование модуля win32net, который должен обеспечить необходимую функциональность.

http://docs.activestate.com/activepython/2.4/pywin32/html/win32/help/win32net.html http://www.blog.pythonlibrary.org/?p=20


предполагая, что вы импортируете необходимые библиотеки, это была часть сервера RPC, где клиент попросил сервер сопоставить диск локально...

#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',)

================Проверьте пробелы отсюда, они были частью функции============

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

У меня нет сервера для тестирования здесь, дома, но, возможно, вы могли бы просто использовать модуль подпроцесса стандартной библиотеки для выполнения соответствующей команды NET USE?

глядя на NET HELP USE из командной строки windows, похоже, вы сможете ввести пароль и идентификатор пользователя в команде net use для сопоставления диска.

быстрый тест в интерпретаторе команды чистого использования без картографического материала:

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

There are no entries in the list.

0
>>>

Мне было трудно заставить эту линию работать:

win32wnet.WNetAddConnection2 (win32netcon.RESOURCETYPE_DISK, диск, сетевой путь, нет, пользователь, пароль)

но удалось с этим:

win32wnet.WNetAddConnection2 (1, 'Z:', r'\UNCpath\share', нет, 'логин', 'пароль')


Если вы хотите сопоставить текущего пользователя входа в систему, я думаю, что подпроцесс решит вашу проблему. Но вы хотите управлять различными сопоставлениями для разных пользователей из одной главной учетной записи. Вы можете сделать это из реестра windows

идея состоит в том, чтобы загрузить профиль данного пользователя.

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)