?背景:
終極目標:通過python調用大模型,獲得結果,然后根據返回信息,控制AutoIT操作電腦軟件,執行具體工作。讓AI更具有執行力。
已完成部分:
?關于python調用大模型的,可以參考之前的文章:
AI入門7:python三種API方式調用本地Ollama+DeepSeek_deepseek大模型下載到本地后,如何在python代碼中調用-CSDN博客
AI入門8:通過vsCode用python訪問公網deepseek-r1等模型(Tocken模式)-CSDN博客
AutoIT介紹,和如何安裝及配置,以及運行了第一個hello程序,然后學習了基本工具的使用和基本語法,對桌面對象的操控,以及python控制autoit的基本理論,見前面文檔:
【AI飛】AutoIT入門一:AutoIT來了,準備讓AI動起來-CSDN博客
【AI飛】AutoIT入門二:Autolt v3 Window Info,和SciTE Script Editor的使用及鼠標操作-CSDN博客
【AI飛】AutoIT入門三:Autolt基本語法-CSDN博客
【AI飛】AutoIT入門四(重點):Autolt代替你操控計算機就快要實現了~-CSDN博客
【AI飛】AutoIT入門5(GUI-選學):autoit構建GUI,用得上嗎-CSDN博客
【AI飛】AutoIT入門六(拐點):python操控autoit-CSDN博客
本文,繼續python調用AutoIT之后,我實實在在的做了一個具體應用,過程曲折,特此總結記錄。
本節目標
用AutoIT模擬手工操作,只有在沒有其他程序可以替代,且需要重復操作執行,才有必要用AutoIT,我現在就有一堆CSF格式視頻,需要轉換成現在播放器能播放的。
CSF格式是之前大學課堂錄制流行的格式,找了很久的批量轉換方法,連AI都沒有好的解決辦法,嘗試了半天,下載安裝了ScenicEditor,其中帶了個“CSF文件格式轉換工具”,只能一個一個視頻的轉,所以才用python控制autoit批量執行操作。
?準備
需要安裝autoit,入門第一篇中有,另外需要開發環境:Trae或者vscode,其安裝配置可以參考之前的文檔
【Ai工具】trae和傳統編程環境vs+代碼助手的PK,結果大捷_trae cn與通義靈碼對比寫代碼-CSDN博客
還沒安裝python的朋友,可以參考之前的文檔,Trae就是仿照vsCode,操作不能說一模一樣,簡直沒有差別:
【菜鳥飛】用vsCode搭建python運行環境_code運行python環境-CSDN博客
?第一個python操控autoit的程序見:
【AI飛】AutoIT入門六(拐點):python操控autoit-CSDN博客
開始
直接展示一下成功的結果代碼,和實現邏輯,再說其中的“坑”在哪里。
實現業務邏輯
轉換一個文件的過程是這樣:
運行“CSF文件格式轉換工具”,初始界面如下:
?
進行一次轉換,需要進行如下設置:
選擇“源文件路徑”,就是要轉換的文件,選擇之后,主界面的下拉框才有相關選項,
?
然后,是按照上圖設置配置項,特別是目標屏幕文件,得修改默認值為當前設置,然后,點擊“配置”按鈕,進行配置屏幕流量和屏幕幀率。
程序邏輯
輪詢源文件夾,把每一個文件,按上面的過程,處理一遍。
調試好的程序
代碼如下
import os
import autoit
import time# CSF文件格式轉換工具路徑
csf2wmv_exe_path = r"E:\Program Files (x86)\ScenicEditor\csf2wmv.exe"
# 源文件路徑
source_folder = r"E:\教程\"def is_csf2wmv_running():"""檢查 csf2wmv 程序是否已經在運行"""return autoit.win_exists("[TITLE:CSF文件轉換工具]")def setup_conversion_tool(csf_file_path, target_folder):"""設置轉換工具的參數"""# 如果程序未運行,則啟動程序if not is_csf2wmv_running():autoit.run(csf2wmv_exe_path)# 等待主窗口出現if not autoit.win_wait("[TITLE:CSF文件轉換工具]", 10):print("錯誤: CSF文件轉換工具窗口未在10秒內出現")return False# 點擊“...”按鈕選擇源文件路徑autoit.control_click("[TITLE:CSF文件轉換工具]", "Button2") # 點擊“...”按鈕# 等待文件選擇對話框出現if not autoit.win_wait("[CLASS:#32770; TITLE:打開]", 5):print("錯誤: 文件選擇對話框未在5秒內出現")return Falsetime.sleep(1)# 在文件選擇對話框中選擇文件autoit.control_set_text("[CLASS:#32770; TITLE:打開]", "Edit1", csf_file_path)# 等待文件選擇完成time.sleep(1)#autoit.control_focus("[CLASS:#32770; TITLE:打開]", "Button1") # 確保焦點在“打開”按鈕上autoit.control_click("[CLASS:#32770; TITLE:打開]", "Button2") # 點擊“打開”按鈕# 等待文件選擇完成time.sleep(1)# 設置目標文件夾autoit.control_focus("[TITLE:CSF文件轉換工具]", "Edit2")autoit.control_set_text("[TITLE:CSF文件轉換工具]", "Edit2", target_folder)time.sleep(2)#autoit.mouse_move(808,202)#time.sleep(1)autoit.mouse_click("left", 908,302, 1, 0)time.sleep(1)autoit.mouse_click("left", 908,337, 1, 0)time.sleep(3) # 設置其他選項(根據需要調整)# 目標視音頻2文件 try:autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox5") # 選擇屏幕流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox5", "不轉換音頻")time.sleep(3) autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox6") # 選擇音頻流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox6", "不轉換視頻")except Exception as e:"print(csf_file_path)"try:# 目標視音頻1文件 autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox2") # 選擇視頻流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox2", "不轉換視頻") time.sleep(3) autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox1") # 選擇視頻流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox1", "不轉換音頻") except Exception as e:"print(csf_file_path) " # 目標屏幕文件 time.sleep(3) autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox3") # 選擇視頻流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox3", "Screen 01")time.sleep(3) autoit.control_focus("[TITLE:CSF文件轉換工具]", "ComboBox4") # 選擇音頻流autoit.control_send("[TITLE:CSF文件轉換工具]", "ComboBox4", "Audio 01")time.sleep(2) # 新增:點擊“配置”按鈕autoit.control_click("[TITLE:CSF文件轉換工具]", "Button9") # 假設“配置”按鈕的控制名為"Button3"time.sleep(1)# 在彈出的配置界面中設置參數if autoit.win_wait("[TITLE:屏幕配置]", 5): # 等待配置界面出現# 設置屏幕屬性autoit.control_focus("[TITLE:屏幕配置]", "Edit1") # 屏幕流率time.sleep(1)autoit.control_set_text("[TITLE:屏幕配置]", "Edit1", "1200")time.sleep(2)autoit.control_focus("[TITLE:屏幕配置]", "Edit3") # 屏幕幀率time.sleep(1)autoit.control_set_text("[TITLE:屏幕配置]", "Edit3", "25")time.sleep(1)# 點擊“OK”按鈕保存配置autoit.control_click("[TITLE:屏幕配置]", "Button1") # 假設“OK”按鈕的控制名為"Button1"time.sleep(1)return Truedef start_conversion():"""開始轉換"""if not autoit.control_click("[TITLE:CSF文件轉換工具]", "Button1"):print("錯誤: 無法點擊'開始轉換'按鈕")return Falsereturn Truedef main():# 遍歷文件夾中的 .csf 文件for filename in os.listdir(source_folder):if filename.endswith(".csf"):csf_file_path = os.path.join(source_folder, filename)target_folder = source_folder # 假設與源文件在同一目錄下if setup_conversion_tool(csf_file_path, target_folder):if start_conversion():print(f"成功啟動轉換文件: {filename}")# 等待轉換完成(這里簡單地等待一段時間,實際應根據具體情況進行調整)print(f"正在轉換文件: {filename}")time.sleep(20) # 根據實際情況調整等待時間print(f"成功轉換文件: {filename}")else:print(f"失敗啟動轉換文件: {filename}")else:print(f"失敗設置轉換工具參數: {filename}")# 轉換完成后關閉程序(如果需要)if is_csf2wmv_running():#autoit.win_close("[TITLE:CSF文件轉換工具]")print("所有文件轉換完成,程序已關閉。")print("所有文件轉換完成。")if __name__ == "__main__":main()
程序也不長,但是坑太多,AI都整不出來,最后還費了很多時間,連猜帶蒙,才搞出來。
來,盤點一下遇到的哪些“坑”
坑
控件定位坑
有圖有真相:
?
一個button,對應了這個選擇文件的區域,從AutoIt Window Info里,你根本看不出來,源文件選擇的按鈕是哪一個,AI給的程序,它寫的是“Button1”,執行調試的時候,只是下面那個按鈕被點開,我試著改了一下,結果是button2,對應代碼:
?
坑不,工具定位不到區域里的對象,界面控件序號是無序的。。。
?不確定坑
同一個區域,有的控件能單獨被工具捕捉定位,有的不能,特別是你需要定位的,它定位不了,這個下拉框的參數要改,結果你不知道它是老幾。。。
?
這個也在上面區域里,它能被定位到:?
?
?我試了很久,不能相信它對控件還有歧視,掃雷似的,探查半天,沒找到規律。。。
控件靈異坑
看下代碼,其中,49、51行,是用鼠標點擊操作,模擬了第一個選擇視頻流的下拉菜單操作,代碼看著是重復的,但是去掉49、51行,下面的下拉菜單控件,程序就找不到,運行就報錯,找不到對象,控件啥時候出現,怎么出現,這個未解之謎,至今沒找到原因。
?
上面這幾個坑,AI完全避不開,怎么問都問不出所以然。?
霸占系統坑?
程序執行 一起來,如果你碰了鼠標,或切換它用的窗口,它就找不到對象了,所以程序運行起來,你的電腦就被霸占了,只能看著它點來點去,別的啥也別想干了。。。
有用的經驗
sleep的使用
代碼里有很多Sleep,AI給的程序中,沒加,執行的時候,不是控件找不到,就是數據設置不上,交互界面,不一定比人操作速度快,得等等程序。。。
界面對象探查
讓AI寫了一個桌面對象探查的程序,代碼如下:
import autoit
import timedef get_window_info(title):"""獲取指定窗口的信息"""if not autoit.win_exists(title):print(f"窗口 '{title}' 不存在")return None# 獲取窗口類名列表class_list = autoit.win_get_class_list(title)class_name = class_list.split("|")[0] if class_list else None # 取第一個類名window_info = {"title": autoit.win_get_title(title),"text": autoit.win_get_text(title),"class": class_name,"pos": autoit.win_get_pos(title),"handle": autoit.win_get_handle(title)}return window_infodef get_controls_info(title):"""獲取指定窗口內所有控件的信息"""controls_info = []# 獲取窗口句柄hwnd = autoit.win_get_handle(title)if not hwnd:print(f"無法獲取窗口 '{title}' 的句柄")return controls_info# 遍歷窗口內的所有控件control_id = 0while True:control = autoit.control_get_handle(title, "[ID:" + str(control_id) + "]")if not control:breakcontrol_info = {"id": control_id,"class": autoit.control_get_classname(title, "[ID:" + str(control_id) + "]"),"text": autoit.control_get_text(title, "[ID:" + str(control_id) + "]"),"pos": autoit.control_get_pos(title, "[ID:" + str(control_id) + "]")}controls_info.append(control_info)control_id += 1return controls_infodef main():# 窗口標題window_title = "CSF文件轉換工具"# 獲取窗口信息window_info = get_window_info(window_title)if window_info:print("-------窗口信息:----------")for key, value in window_info.items():print(f" {key}: {value}")print("-------窗口信息:結束----------")# 獲取控件信息controls_info = get_controls_info(window_title)if controls_info:print("\n======》控件信息:")for control in controls_info:print(" 控件信息:")for key, value in control.items():print(f" {key}: {value}")if __name__ == "__main__":# 確保 CSF文件轉換工具 窗口已經打開print("請確保 'CSF文件轉換工具' 窗口已經打開...")time.sleep(2) # 等待2秒,確保窗口已經打開main()
窗口信息能探索出來,控件信息AI改了多次,探查不出來,窗口信息中,class參數收集了窗口控件的類型和文本信息,具有一定參考性:
我把輸出的text和class信息,對應起來,和控件界面對照了一下:
可以參考著,調試代碼:
看著有點用。
結尾:
千言萬語,就一句話:AI的盡頭,還是是人腦,嘿嘿😊😊😊。。。
另一句話,pyautoit的資料真的少,連中文API文檔都沒有,都沒有。。。