如何用Python 3+访问远程Windows机器并复制文件?现有方法失败求助
Python 3+ 实现从远程Windows机器复制文件到本地的解决方案
嘿,我明白你现在在机器A上折腾用Python连接远程Windows机器B复制文件,之前用win32net和wmi都踩了不少坑对吧?咱们先聊聊你之前遇到的问题,再给你几个更靠谱的替代方案。
先排查你之前的错误
win32Net的参数问题
你碰到的(87, 'NetUseAdd', 'The parameter is incorrect.')错误,其实是因为data字典的参数格式不对——虽然微软文档说第一个参数可以设为None,但data里的local字段如果不需要映射成本地驱动器,应该设为空字符串,而不是C:。另外还要注意:
- 目标机器的
C$管理员共享是否开启(默认是开启的,但可能被禁用) - 机器A和B是否在同一工作组/域
- 防火墙有没有放行SMB流量(默认445端口)
至于用目标IP当第一个参数出现的1326错误,大概率是用户名格式不对——Windows远程登录需要用机器名\用户名或者域名\用户名的格式,别只写用户名,试试改成目标机器名\AccountUserName再试。
WMI的登录问题
WMI的错误同样可能是用户名格式的锅,另外还要确认:
- 目标机器的WMI服务是否正常运行
- 防火墙是否允许WMI的端口(默认135端口+动态端口)
- 你的账户有没有访问WMI的权限
推荐的替代方案
方案1:用smbclient直接操作SMB共享
这个库专门针对SMB协议设计,比win32net更直观,支持Python 3+。
先安装库:
pip install smbclient
示例代码:
import smbclient # 连接远程SMB共享 with smbclient.SMBClient( server_ip="IP.IP.IP.IP", username="目标机器名\\AccountUserName", # 必须是机器名/域名+用户名格式 password="AccountPassword" ) as client: # 把远程文件下载到本地 client.download( remote_path="C$/path/to/your/target_file.txt", # C$是管理员共享,换成你的文件路径 local_path="C:/local/save/path/target_file.txt" )
小贴士:如果目标机器禁用了
C$共享,你可以在机器B上手动创建一个普通共享文件夹,把remote_path改成共享文件夹名/path/to/file.txt就行。
方案2:用paramiko通过SSH/SFTP复制(需开启OpenSSH)
如果你的机器B能开启SSH服务,这个方案更通用,跨平台也能用。Windows 10/11现在自带OpenSSH服务器,安装很方便:
- 打开设置 -> 应用 -> 可选功能 -> 添加功能,搜索并安装
OpenSSH服务器 - 启动OpenSSH服务(服务里找
sshd,设为自动启动)
然后安装paramiko:
pip install paramiko
示例代码:
import paramiko ssh_client = paramiko.SSHClient() # 自动添加远程主机密钥(生产环境建议手动验证) ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 连接远程机器 ssh_client.connect( hostname="IP.IP.IP.IP", username="AccountUserName", password="AccountPassword", port=22 # 默认SSH端口 ) # 开启SFTP会话 sftp = ssh_client.open_sftp() # 远程文件路径 -> 本地保存路径 sftp.get("/path/to/remote/file.txt", "C:/local/save/path/file.txt") sftp.close() finally: # 确保关闭连接 ssh_client.close()
方案3:用subprocess调用Windows原生命令(无第三方库)
如果不想装额外的库,可以直接调用Windows的net use建立连接,再用robocopy复制文件(比xcopy更稳定)。
示例代码:
import subprocess # 先建立网络连接 net_use_cmd = f'net use \\\\IP.IP.IP.IP\\C$ "AccountPassword" /user:"目标机器名\\AccountUserName"' # 执行命令,check=True会在命令出错时抛出异常 subprocess.run(net_use_cmd, shell=True, check=True) # 用robocopy复制文件,robocopy返回0-7都是正常状态,所以不要加check=True robocopy_cmd = 'robocopy \\\\IP.IP.IP.IP\\C$\\source_folder C:\\local_dest_folder target_file.txt' subprocess.run(robocopy_cmd, shell=True) # 可选:用完断开连接 subprocess.run('net use \\\\IP.IP.IP.IP\\C$ /delete', shell=True)
最后再提几个注意点
- 先ping一下目标IP,确保机器A和B网络连通
- 目标机器防火墙要放行对应的端口:SMB用445,SSH用22
- 所用的账户必须有目标机器共享文件夹的读取权限
内容的提问来源于stack exchange,提问作者Conk
相关产品推荐
相关产品推荐

