【问题标题】:What is the best way to map windows drives using Python?使用 Python 映射 Windows 驱动器的最佳方法是什么?
【发布时间】:2010-11-19 06:28:45
【问题描述】:

使用 Python 将网络共享映射到 Windows 驱动器的最佳方法是什么? 此共享还需要用户名和密码。

【问题讨论】:

    标签: python windows mapping drive


    【解决方案1】:

    基于@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)
    

    我更喜欢这种简单的方法,尤其是在所有信息都是静态的情况下。

    【讨论】:

    • 我对此设置有疑问。当您尝试在 Web 应用程序中映射驱动器时,驱动器是映射到运行该应用程序的用户还是服务器?
    • 使用'net use a: /del /Y'强制,否则会一直挂在请求确认删除
    • 另外,如果我们使用 'net use * ' + "\\UNC path\folder" 它会自动找到一个空的驱动器插槽来挂载 "UNC\path\folder"
    【解决方案2】:

    好的,这是另一种方法...

    这个是通过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
    

    要取消映射,只需使用....

    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
    

    【讨论】:

    • 使用win32wnet.WNetAddConnection2win32wnet.WNetCancelConnection2 是个好主意。但是捕获异常并返回返回码似乎是不必要的。内置异常已经为您提供了良好的返回信息。此外,捕捉空的except 也不是一个好习惯。
    【解决方案3】:

    我家里没有服务器可以测试,但也许你可以简单地使用标准库的子进程模块来执行适当的 NET USE 命令?

    从 Windows 命令提示符查看 NET HELP USE,看起来您应该能够在 net use 命令中输入密码和用户 ID 来映射驱动器。

    在没有映射内容的裸网使用命令的解释器中进行快速测试:

    >>> import subprocess
    >>> subprocess.check_call(['net', 'use'])
    New connections will be remembered.
    
    There are no entries in the list.
    
    0
    >>>
    

    【讨论】:

      【解决方案4】:

      假设您导入了必要的库,这是 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
      

      【讨论】:

        【解决方案5】:

        子流程的替代方案:

        import os
        
        os.system("net use m: \\\\shared\folder")
        

        或者

        import os
        
        cmd = "net use m: \\\\shared\folder"
        os.system(cmd)
        

        【讨论】:

          【解决方案6】:

          我无法让这条线路正常工作:

          win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, drive, networkPath, None, user, password)

          但是成功了:

          win32wnet.WNetAddConnection2(1, 'Z:', r'\UNCpath\share', 无, '登录名', '密码')

          【讨论】:

            【解决方案7】:

            如果您想映射当前登录用户,我认为 subprocess 可以解决您的问题。但是您是否想从一个主帐户控制不同用户的不同映射。您可以从 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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-10-21
              • 1970-01-01
              • 1970-01-01
              • 2011-10-14
              • 2012-07-03
              • 1970-01-01
              相关资源
              最近更新 更多