影刀RPA | Win端沒有"上傳文件"指令? 多少有點(diǎn)離譜了刀刀
背景说明
过去开发的RPA应用多是基于网页端的,在一些“上传文件”的场景,直接使用官方的“上传文件”指令就OK,当时也觉得是个挺基础的指令,桌面端指定也有!
直到后来开发一个桌面自动化应用时,需要用到这个“上传文件(Win)”指令,在影刀的指令库一顿翻箱倒柜,试图找到这个指令,“搜索+分组逐一查看”,都没有,不死心,又去社区里搜索相关帖子,
最终确认:桌面端目前真的没有"上传文件"指令,这个看似基础的功能只在网页自动化中提供!
啊不是🥲,连"上传文件"都要用户自己造轮子吗刀刀!?
吐槽归吐槽,抱怨不如行动。
本文将基于此背景,分享2个解决方案,供铁铁们应用参考。
方案01:剪切板路径粘贴法
这个简单,想想正常我们是怎么上传文件的?
点击Win元素,等待文件对话框出现,在地址栏输入文件路径,点"确定/打开",好,那我们就让RPA也这样做~
1. 技术原理
将文件路径置于剪切板,利用Windows剪贴板在文件选择对话框中Ctrl+V粘贴键入文件路径,并按Enter回车。
2. 实现步骤
-
将目标文件路径存入变量filePath
-
执行"设置剪贴板文本"指令,参数为 filePath
-
点击目标应用的"打开/上传" Win元素,触发文件对话框
-
等待文件对话框出现(根据实际情况自主添加,可设置合理等待时间)
-
键盘输入:“Ctrl+V”+“Enter”
方案2:手搓“上传文件## 这里是标题文字(Win)”
既然没有现成的指令,那我们能不能自己DIY一个呢,写一个流程,然后封装成"上传文件(Win)"的自定义指令,这样,后面无论哪个桌面自动化应用需要使用,拖拽一条指令就能实现~
1. 技术原理
使用pywinauto进行GUI自动化,并结合剪贴板和键盘模拟,实现文件选择对话框的自动操作。并且需要考虑多种异常情况和不同的对话框标题,以及对变量输入、文件路径等的支持。
此处致谢社区 @Code拾光者 提供的解决思路参考:
https://www.yingdao.com/community/detaildiscuss?id=810902009826361344
2. 实现步骤(直接看图吧)
新建一个桌面自动化应用,进行如下图中的搭建和参数设置,搞好了退出应用,执行"发版",就可以在其他应用中调用该自定义指令。
1. 流程参数配置(主流程下新建)
2. 主流程完整指令截图(放大看)
3. 代码
01-Python模块管理:安装下面两个包
02-Python代码
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep
from . import package
from .package import variables as glv
import pywinauto
from pywinauto.keyboard import send_keys
import pyperclip
import time
from pywinauto.timings import TimeoutError
def main(dir_path="", file_names="", wait1=20, wait2=0.5):
"""
自动化文件选择对话框操作
参数:
dir_path (str): 要选择的目录路径,默认为空
file_names (str): 要选择的文件名,默认为空
wait1 (int): 等待文件对话框出现的超时时间(秒),默认20
wait2 (float): 等待文件夹加载的超时时间(秒),默认0.5
"""
try:
xbot.print(f"开始操作 - 路径: {dir_path}, 文件: {file_names}, 等待1: {wait1}s, 等待2: {wait2}s")
app = pywinauto.Desktop()
# 1. 增强的窗口查找逻辑
start_time = time.time()
dlg = None
possible_titles = [
"选择文件", "选择文件Dialog",
"打开", "打开Dialog", "Open",
"另存为", "Save As",
"文件资源管理器", "浏览",
"选择文件夹", "选择目录"
]
while time.time() - start_time < wait1:
try:
# 先尝试通过窗口类查找(标准文件对话框类)
try:
dlg = app.window(class_name="#32770")
if dlg.exists():
xbot.print("通过窗口类找到对话框")
break
except:
pass
# 尝试所有可能的对话框标题
for title in possible_titles:
try:
dlg = app[title]
xbot.print(f"成功找到窗口: {title}")
break
except:
continue
if dlg:
break
xbot.sleep(0.5)
except Exception as e:
xbot.print(f"窗口查找异常: {str(e)}")
xbot.sleep(0.5)
continue
if dlg is None:
available_windows = "\n".join([str(w) for w in app.windows()])
raise TimeoutError(f"文件对话框未在{wait1}秒内出现. 当前可用窗口:\n{available_windows}")
# 2. 使用剪贴板方式输入路径
try:
# 改进的地址栏定位方法
try:
dlg["Toolbar3"].click()
except:
try:
dlg.type_keys("%d") # Alt+D 聚焦地址栏
except:
dlg.Edit.set_focus()
pyperclip.copy(dir_path)
xbot.sleep(0.2)
send_keys("^a") # Ctrl+A
send_keys("^v") # Ctrl+V
send_keys("{VK_RETURN}") # Enter
except Exception as e:
raise Exception(f"路径输入失败: {str(e)}")
# 清空剪贴板
pyperclip.copy("")
# 3. 等待文件夹加载
xbot.sleep(wait2)
# 4. 使用剪贴板方式输入文件名
try:
pyperclip.copy(file_names)
xbot.sleep(0.2)
# 尝试多种方式定位文件名输入框
try:
dlg["文件名(&N):Edit"].type_keys("^a")
dlg["文件名(&N):Edit"].type_keys("^v")
except:
try:
dlg["File name:Edit"].type_keys("^a")
dlg["File name:Edit"].type_keys("^v")
except:
dlg["Edit"].type_keys("^a")
dlg["Edit"].type_keys("^v")
except Exception as e:
raise Exception(f"文件名输入失败: {str(e)}")
# 5. 点击打开按钮
try:
# 尝试多种方式定位打开按钮
try:
dlg["打开(&O)"].click()
except:
try:
dlg["Open"].click()
except:
dlg.type_keys("{TAB}{TAB}{ENTER}")
except Exception as e:
raise Exception(f"点击打开按钮失败: {str(e)}")
# 清空剪贴板
pyperclip.copy("")
return True
except Exception as e:
xbot.print(f"操作失败: {str(e)}")
# 确保无论如何都清空剪贴板
pyperclip.copy("")
return False
第二个方案是我实测3款软件可以正常运行的,不一定适配所有桌面软件(感觉迟早会翻车hhh~
以上不懂的可以滑到底面联系我,最后,@影刀官方,咱是不是该考虑把这个功能加上了啊?像"上传文件"这样基础的指令居然需要用户大费周章去实现,太抓马了~🤣🤣
铁铁们,你们有没有遇到过类似的问题呢?欢迎在评论区分享你的血泪史和解决方案,我们下期再见!
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章