使用WinSCP自动下载文件时无法访问列表控件中的文件
WinSCP自动遍历文件并打开当日最新文件的解决方案
问题描述
我计划在远程桌面执行脚本,通过WinSCP每日自动下载文件。目前脚本已完成登录并进入资源管理器窗口,但无法访问窗口内的文件,需要实现遍历文件列表并打开指定日期的最新文件。文件命名格式为YYYY-MM-DD-0001、YYYY-MM-DD-0002等,需打开对应日期的最新文件。
现有代码
import pywinauto from pywinauto.application import Application from pywinauto.keyboard import send_keys from pywinauto import keyboard as kb import time HOST_NAME = '' USER_NAME = '' PASSWORD = '' PORT_NUMBER = '' DIRECTORY = '' main_app = Application(backend='uia').start(cmd_line=r"C:\Program Files (x86)\WinSCP\WinSCP.exe").connect(title='WinSCP', timeout=10) main_dlg = main_app.window(title='WinSCP') main_dlg.set_focus() Login_app = Application().connect(title=u'Login', class_name='TLoginDialog', timeout=10) Login_dlg = Login_app.window(title=u'Login', class_name='TLoginDialog') Login_dlg.set_focus() Login_dlg.wait('ready', timeout=10) Login_dlg['Edit1'].set_text(PORT_NUMBER) # Port Number Login_dlg['Edit2'].set_text(PASSWORD) # Password Login_dlg['Edit3'].set_text(USER_NAME) # User name Login_dlg['Edit4'].set_text(HOST_NAME) # Host Name Login_dlg['Button5'].click() # Login appExplorer = Application().connect(title_re='.*' + HOST_NAME + ' - WinSCP', class_name="TScpExplorerForm", timeout=10) winExplorer = appExplorer.window(title_re='*- carestreamhealth@' + HOST_NAME + ' - WinSCP', class_name='TScpExplorerForm') winExplorer.wait('visible',timeout=10) winExplorer.set_focus() winExplorer.TTBXToolbar4.click_input() # click into Address bar winExplorer.TTBXToolbar4.TTBXEdit.set_text(DIRECTORY) send_keys('{ENTER}') winExplorer.wait('ready', timeout=10)
解决方案
核心问题与思路
现有代码未正确定位WinSCP的文件列表控件,且默认的win32后端对WinSCP文件区域支持有限。需切换到UIA后端识别文件列表,再通过文件名规则筛选当日最新文件。
修改后的完整代码
import pywinauto from pywinauto.application import Application from pywinauto.keyboard import send_keys import time from datetime import datetime HOST_NAME = '' USER_NAME = '' PASSWORD = '' PORT_NUMBER = '' DIRECTORY = '' # 启动WinSCP并连接主窗口 main_app = Application(backend='uia').start(cmd_line=r"C:\Program Files (x86)\WinSCP\WinSCP.exe") main_dlg = main_app.window(title='WinSCP').wait('ready', timeout=10) main_dlg.set_focus() # 处理登录窗口 Login_dlg = main_app.window(title='Login', class_name='TLoginDialog').wait('ready', timeout=10) Login_dlg.set_focus() # 填写登录信息(控件顺序若无效,可通过inspect.exe确认) Login_dlg['Edit4'].set_text(HOST_NAME) # Host Name Login_dlg['Edit3'].set_text(USER_NAME) # User name Login_dlg['Edit1'].set_text(PORT_NUMBER) # Port Number Login_dlg['Edit2'].set_text(PASSWORD) # Password # 点击登录 Login_dlg['Button5'].click() # 等待资源管理器窗口加载,使用UIA后端连接 time.sleep(3) appExplorer = Application(backend='uia').connect(title_re=f".*{HOST_NAME} - WinSCP", class_name="TScpExplorerForm", timeout=15) winExplorer = appExplorer.window(title_re=f".*- carestreamhealth@{HOST_NAME} - WinSCP", class_name='TScpExplorerForm') winExplorer.wait('visible', timeout=15) winExplorer.set_focus() # 导航到目标目录 winExplorer.TTBXToolbar4.click_input() winExplorer.TTBXToolbar4.TTBXEdit.set_text(DIRECTORY) send_keys('{ENTER}') winExplorer.wait('ready', timeout=10) time.sleep(2) # 等待目录加载完成 # 获取文件列表控件(优先List,无效则尝试Table) try: file_list = winExplorer.child_control(type='List', found_index=0) except: file_list = winExplorer.child_control(type='Table', found_index=0) # 获取当日日期字符串 today_str = datetime.today().strftime('%Y-%m-%d') # 筛选当日最新文件 target_file = None max_seq = 0 for item in file_list.items(): file_name = item.text() # 跳过目录,只处理文件 if not file_name.endswith('/') and today_str in file_name: seq_part = file_name.split('-')[-1] if seq_part.isdigit(): seq = int(seq_part) if seq > max_seq: max_seq = seq target_file = item # 打开目标文件 if target_file: target_file.double_click_input() print(f"已打开当日最新文件:{target_file.text()}") else: print(f"未找到{today_str}日期的文件")
关键说明
- UIA后端切换:连接资源管理器窗口时指定
backend='uia',WinSCP的文件列表在UIA模式下更易识别。 - 控件定位:通过
child_control查找文件列表,若List类型无效可切换为Table(不同WinSCP版本可能有差异,可用inspect.exe确认控件类型)。 - 文件筛选:提取文件名中的日期和序号,筛选出当日文件后比较序号大小,取最大值对应的文件。
- 等待机制:添加
time.sleep()确保页面加载完成,避免网络延迟导致控件查找失败。
内容的提问来源于stack exchange,提问作者rdg515
相关产品推荐
相关产品推荐

