今天聽到同事提到AutoIT,可以用來測試GUI窗口。了解一下這個工具。
以下內容引自: http://www.jb51.net/article/14870.htm (此url非原出處,該博主未注明原出處)
autoit入門教程小結 第1/5頁
轉載 2008-06-19
作者: yonken
據我了解需要編寫AutoHotkey/AutoIt腳本來實現自動化操作的用戶很多都是網管,其它則可能是一些個人用戶,他們一般都具有相當的技術水平,而且都希望能借助腳本來完成某些以往需要人工操作的重復性勞動,但限於語言條件上的限制可能對官方的幫助文檔有較難理解之處。為方便讀者,我將從最簡單的說起,每個示例盡可能同時給出相應的AHK和AU3版本代碼。本文將盡可能用較通俗的語言描述,但並不打算講解語法基礎,所以不一定適合新手閱讀。
文中涉及到的AHK/AU3版本:
AutoHotkey
1.0.44 .08
AutoIt
3.1.1
一、關於腳本
1、什么是腳本?
這是個非常“流行”的術語了,通俗而言腳本(Script)一般都是指根據某種語法規則編寫的具有特定格式的文本文件。可能大家已經聽說過很多種腳本:VBScript、JScript、PHP、ASP、JSP、CGI、CS腳本,甚至游戲外掛腳本。
這些腳本文件都是可執行文件,可執行相應的操作。
AHK 腳本文件擴展名:*.ahk
AU3 腳本文件擴展名:*.au3
2、腳本和程序的不同?
嚴格來說,所謂“程序”就是指以各種編程語言(比如說C/C++/C#/Delphi)編寫、由編譯器編譯好后的二進制文件,一般就是機器代碼,可由系統執行。而腳本則是只是些純文本文件,包含了各種定義好的命令,這一點很像批處理文件。這樣,我們得出一個簡單的結論,那就是用戶一般無法獲得“程序”的源代碼,我們只能進行反匯編把它逆向還原為匯編語言代碼(或其它),當然,也有些“程序” 是可以獲得源代碼的(比如Java);腳本則是用戶可直接查看的代碼文件,而AHK/AU3則提供了把腳本文件“轉換”成exe文件的方法。
3、腳本如何運行?
腳本是“解釋性”的語言,它的運行依賴一個“解釋器”,由這個解釋器來“翻譯並解釋”腳本的每條命令(或者說代碼),然后執行相應操作。如果不嚴格定義的話,HTML和Java都可以認為是解釋性語言。AHK/AU3的主程序(分別是AutoHotkey.exe和AutoIt3.exe)就是它們的“解釋器”,上面提到腳本可“轉換”成可脫離相應的解釋器而獨立運行的exe可執行文件,而我們還可以使用相應的工具把它們“還原”成腳本文件,由此我們完全可以這么理解:腳本代碼是被“壓縮”到這個exe文件中,解釋器也是在里面,在運行exe時實際上是先“解壓”腳本代碼然后運行解釋器並解釋該腳本。
4、如何創建腳本?
使用資源管理器的右鍵菜單即可創建相應腳本文件,或者新建一個文本文件后改擴展名即可。
5、稍微介紹一點語法規則?
A)對AHK而言,每個內建的功能都是以“命令”的形式提供:
Command, param1, param2,…
而AU3則以“函數”的形式提供:
Function(param1, param2, …)
命令或函數中被符號“[”和“]”圍住的參數是可選參數,表示在使用這些命令或函數時可省略它們(不給出具體數值)。
若某個參數含有空格,則最好使用雙引號圍住該參數。
B)解釋器自上而下(從第一行到最后一行)“解釋”腳本的每行語句,除非遇到“Return”、“Goto”、“Gosub”、“Exit”等語句、函數、熱鍵或其它能使腳本“跳”到某個標識符的條件成立。
C)關鍵字和標識符(包括變量名、命令名、函數名等)都不區分大小寫。
二、運行程序或打開文件
1、運行程序
Run t命令或者函數用來運行外部可執行文件,AHK還可利用它來直接打開文件。
AHK:
Run, 目標文件 [, 工作目錄, Max|Min|Hide|UseErrorLevel, 輸出PID變量]
AU3:
Run ( "文件名" [, "工作目錄" [, 標志]] )
【示例 2.1.1 】
AHK:
Run, Notepad.exe
AU3:
Run("Notepad.exe")
上面的示例中都沒有給出程序“Notepad.exe”的路徑,為什么仍能執行?這是因為它們都會自動在腳本所在目錄下搜尋目標文件,如有則運行,否則就到系統文件夾(%PATH%)中搜尋。
注意:
A)某些程序必須給定“工作目錄”才能成功運行!
B)給出完整的文件路徑有助於輕微提高程序的可靠性。
C)AHK的Run命令可以用來運行程序和直接打開文件,而AU3的Run函數則只能用來運行程序(可執行文件)或傳遞參數讓某個程序打開目標文件。
當然,運行程序的功能還不僅僅是這么簡單,我們還可以指定運行程序的初始狀態,比如讓運行的記事本窗口以最大化狀態顯示(或者最小化、隱藏):
【示例 2.1.2 】
AHK:
Run, Notepad.exe, , Max
AU3:
Run("Notepad.exe", "", @SW_MAXIMIZE)
2、打開文件
前面已經提到,AHK的Run命令可以直接打開文件,而AU3的Run函數則只能用來運行程序,因此在打開文件的方式上有點不同:AHK腳本中可直接給出目標文件,而AHK將自動運行該文件的關聯程序來打開它;而AU3則必須由用戶自己傳遞參數讓某個程序打開目標文件。
【示例 2.2.1 】
AHK:
Run, MyFile.txt
Run, Notepad.exe MyFile.txt
AU3:
Run("Notepad.exe MyFile.txt")
3、以命令行形式運行程序
可以考慮運行系統的命令行解釋器(cmd.exe/command.com),然后指定要執行的命令並傳遞參數。
假設我們要執行命令“dir C:\WINDOWS\system 32” ,用以列出指定目錄的所有文件及子目錄。
【示例 2.3.1 】
AHK:
Run, %ComSpec% /k dir C:\WINDOWS\system32
AU3:
Run(@ComSpec & " /k dir C:\WINDOWS\system32")
注意:
A)ComSpec是腳本內建的用以指示命令行解釋器位置的變量或宏。
B)/k 參數表示“執行字符串指定的命令但保留”,若改為 /c 則表示“執行字符串指定的命令然后終斷”。對此比較直觀的解釋是 /k 將在執行完命令后保留命令提示窗口,而 /c 則將在執行完命令之后關閉命令提示窗口。
C)符號“&”是AU3定義的字符串連接符。
4、特殊應用
A)打開網頁
【示例 2.4.1 】
AHK:
Run, www.autohotkey.com
Run, %A_ProgramFiles%\Internet Explorer\IEXPLORE.EXE www.autohotkey.com
AU3:
Run(@ProgramFilesDir & "\Internet Explorer\IEXPLORE.EXE www.autohotkey.com")
B)打開特殊文件夾
系統的某些特殊文件夾被定義了相應的CLSID(請查看幫助文檔),我們可利用它來打開相應的文件夾,比如打開回收站:
【示例 2.4.2 】
AHK:
Run ::{645ff040-5081-101b -9f 08-00aa 002f 954e}
AU3:
不適用!
C)運行控制面板工具
微軟已經為我們提供了通過命令行打開控制面板某個工具或項目的方式,比如打開系統屬性窗口:
【示例 2.4.3 】
AHK:
Run control sysdm.cpl
AU3:
Run("control sysdm.cpl")
關於訪問控制面板項目的詳細介紹請查看此文:文章地址。
D)指定搜索位置並打開搜索窗口
假設我們要打開一個搜索窗口,而且要指定搜索位置,比如C:\:
【示例 2.4.4 】
AHK:
Run, find C:\
AU3:
不適用!
E)顯示指定文件的屬性窗口
假設我們要打開文件“MyFile.txt”的屬性窗口,則使用關鍵字properties 然后接上目標文件即可:
【示例 2.4.5 】
AHK:
Run, properties MyFile.txt
AU3:
不適用!
注意:AHK在退出前將自動關閉打開的屬性窗口!
F)用“資源管理器”打開指定文件夾
我們知道使用Run, explorer C: 或Run("explorer C:") 即可打開指定的文件夾,可是有時候我們需要在資源管理器中打開它,這時可使用關鍵字 explore:
【示例 2.4.6 】
AHK:
Run, explore C:
AU3:
run("explorer.exe /e,C:\")
G)打印指定文件
要打印指定文件,可使用關鍵字 print:
【示例 2.4.7 】
AHK:
Run, print MyFile.txt
AU3:
不適用!
F)用“資源管理器”打開指定文件夾
我們知道使用Run, explorer C: 或Run("explorer C:") 即可打開指定的文件夾,可是有時候我們需要在資源管理器中打開它,這時可使用關鍵字 explore:
【示例 2.4.6 】
AHK:
Run, explore C:
AU3:
不適用!
run("explorer.exe /e,d:\")
這樣就可以做到你說的打開樹狀文件了
注意:窗口標題和窗口文本參數總是對大小寫敏感的。
1、等待窗口系列命令/函數
AHK和AU3都提供了用法類似的一組窗口等待命令/函數:WinWait/WinWaitActive/WinWaitClose。
它們分別用於等待窗口出現、等待窗口被激活、等待窗口被關閉。由於這些命令/函數的參數類似,現僅以WinWait為例說明。
AHK:
WinWait [, 窗口標題, 窗口文本, 超時時間, 排除標題, 排除文本]
AU3:
WinWait ( "窗口標題" [, "窗口文本" [, 超時時間]] )
WinWait 的作用是在目標窗口出現之前不再執行后面的所有語句。
假設我們要運行記事本程序,並在其窗口出現時提示用戶:
【示例 3.1.1 】
AHK:
Run Notepad
WinWait, 無標題 - 記事本
MsgBox 記事本窗口已被打開!
AU3:
Run("Notepad")
WinWait("無標題 - 記事本")
MsgBox(0, "", "記事本窗口已被打開!")
2、激活窗口相關命令/函數
讓目標窗口成為活動窗口的辦法就是激活它,可用的命令/函數是WinActivate:
AHK:
WinActivate [,窗口標題, 窗口文本, 排除標題, 排除文本]
AU3:
WinActivate ( "窗口標題" [, "窗口文本"] )
3、關閉窗口
關閉窗口有兩種方式,一種是正常的關閉窗口(WinClose),另一種則是強行關閉窗口(WinKill):
AHK:
WinClose/WinKill [,窗口標題, 窗口文本, 超時時間,, 排除標題, 排除文本]
AU3:
WinClose/WinKill ( "窗口標題" [, "窗口文本"] )
現在我們已經可以實現一個比較簡單的功能了,比如我們可以打開系統屬性窗口並等待其出現,窗口出現后激活它,接着等待3秒再關閉它:
【示例 3.1.2 】
AHK:
Run, Sysdm.cpl
WinWait, 系統屬性
WinActivate, 系統屬性
WinWaitActive, 系統屬性
Sleep, 3000
WinClose, 系統屬性
WinWaitClose, 系統屬性
AU3:
Run("Control Sysdm.cpl")
WinWait("系統屬性")
WinActivate("系統屬性")
WinWaitActive("系統屬性")
Sleep(3000)
WinClose("系統屬性")
WinWaitClose("系統屬性")
建議:如果程序中頻繁地出現要用到這些窗口標題的地方,會帶來一個問題:腳本的可讀性,也許你會想,這不是很直觀嗎?可問題是如果這個重復出現的窗口標題是個很長的字符串呢?這將嚴重影響整個代碼的排版美觀。而且我們也無從了解這些窗口標題的“來頭”,不知道這個窗口標題究竟是怎么來的。而如果我們定義一個變量(假設變量名是“AppWindow1”)保存這個窗口標題,我們就能在命令/函數中用變量來表示它,這樣就達到了讓代碼用意更清晰一點的目的。另外,就算目標軟件因某些原因(比如升級)而改變了它的窗口標題,我們也能很方便地作出修改。
4、更准確的標識窗口的方法(主要針對AHK腳本)
程序在運行時起碼會有一個進程,如果能獲得這個進程ID就能在一定程度上保證對窗口的准確標識。另外,每個窗口都有定義窗口類名(Class,比如說記事本窗口的類名就是Notepad),所以我們可以以此排除與目標窗口不同的其它窗口類。其實,我們還有一個更准確的方法:
每個窗口(包括控件在內)都被Windows指派了一個可區別於其它窗口的唯一的標識符(ID),我們稱之為窗口句柄(HWND)。
直接給定窗口標題來表示窗口的一個缺點就是無法保證在腳本運行的過程中始終以該窗口為操作目標,因為在這個過程中很有可能會有其它“同名”窗口(或者說滿足匹配條件的窗口)出現,而如果我們使用這個標識符來表示窗口自然就能保證命令/函數的操作窗口總是同一個窗口了。
我們先來了解一下獲得窗口句柄的命令/函數:
AHK:
WinGet[, 輸出變量, ID, 窗口標題, 窗口文本, 排除標題, 排除文本]
AU3:
WinGetHandle ( "窗口標題" [, "窗口文本"] )
其中WinGet獲得的窗口ID將通過“輸出變量”返回,而WinGetHandle的返回值就是獲得的窗口ID。
我們在進行自動化操作時是要先運行某個程序,如何獲得這個程序成功運行后顯示的窗口句柄?一個比較保險的辦法是先獲得這個程序的進程ID,然后根據這個進程ID獲得它的窗口句柄,AHK支持使用進程ID作為窗口標題使用;但AU3不支持這樣使用,只能先獲得該窗口的類名再根據該類名來獲得窗口句柄(不夠保險):
【示例 3.1.3 】
AHK:
Run, NotePad, , , ThisPID
WinWait, ahk_pid %ThisPID%
;這里的ahk_pid表明跟在后面的變量是進程ID
WinGet, ThisID, ID, ahk_pid %ThisPID%
;ThisID將保存獲得的窗口句柄
AU3:
Opt("WinTitleMatchMode", 4)
Run("Notepad")
$handle = WinGetHandle("classname=Notepad")
現在暫且先忘記了AU3吧,因為它的窗口函數一般都不支持使用窗口句柄作為(窗口標題)參數。
至於如何在AHK中使用窗口句柄,簡單的說,凡是有“窗口標題”參數的命令就可以用窗口句柄來代替,比如:
【示例 3.1.4 】
AHK:
Run, Notepad, , , ThisPID
;先獲得運行的記事本程序的進程ID
WinWait, 無標題 - 記事本 ahk_pid %ThisPID%
;等待該進程窗口的出現
WinGet, ThisHWND, ID, 無標題 - 記事本 ahk_pid %ThisPID%
;獲得窗口句柄
WinActivate, ahk_id %ThisHWND%
;這里的ahk_id表明跟在后面的變量是窗口句柄
WinWaitActive, ahk_id %ThisHWND%
Sleep, 3000
WinClose, ahk_id %ThisHWND%
WinWaitClose, ahk_id %ThisHWND%
1、模擬鼠標點擊(按鈕等)控件
既然是模擬用戶操作,自然就包括了模擬鼠標點擊在內。
適用命令/函數:Click/MouseClick/ControlClick
其中Click/MouseClick用來模擬用戶的物理操作(點擊),把鼠標點擊事件發送到指定坐標位置(相對當前窗口或絕對位置)上,但這種方法並不能保證100%的准確性,屏幕分辨率、用戶干擾和系統環境等都會影響到它們的執行結果,而ControlClick則直接把鼠標點擊事件發送到目標窗口的目標控件上,因而更准確,一般我們不考慮使用坐標位置方式的點擊,下面僅以ControlClick為例說明:
AHK:
ControlClick [, 目標控件或坐標位置, 窗口標題, 窗口文本, 鼠標按鈕, 點擊次數, 選項,排除標題, 排除文本]
AU3:
ControlClick ( "窗口標題", "窗口文本", 控件ID [, 按鈕] [, 點擊次數]] )
對AHK而言,“目標控件”參數是指要點擊的控件的類別名(ClassNN)或控件文本,另外還可以使用控件句柄(若用的是控件句柄則第一個參數需留空,並在第二個參數中使用ahk_id %控件句柄%)。
Q:用什么工具來獲得目標控件的這些信息呢?
A:AHK用戶請使用 AutoIt3 Window Spy,AU3用戶則請使用AutoIt Window Info,你可以在相應的開始菜單項目里找到它們,或者到安裝目錄下尋找。
Q:如何使用這兩個工具?
A:先打開你要進行操作的目標窗口,然后運行 AutoIt3 Window Spy 或 AutoIt Window Info,接下來就是把鼠標移到目標控件上(比如某個按鈕):
AutoIt3 Window Spy 使用演示截圖:
AutoIt Window Info 使用演示截圖:
現在我們假設已打開並激活了“系統屬性”窗口,而任務是點擊它的“確定”按鈕,則可用以下幾種方法:
【示例4.1.1】
AHK:
ControlClick, 確定, 系統屬性
ControlClick, Button2, 系統屬性
AU3:
ControlClick("系統屬性", "", 1)
ControlClick("系統屬性", "", "Button2")
ControlClick("系統屬性", "", "確定")
提醒:即使目標窗口或控件是隱藏狀態,ControlClick命令還是可以“點擊”目標控件,但不能保證成功率。
2、模擬鍵盤操作
鍵盤也是我們在操作窗口時會用到的工具,比如說在安裝軟件的時候經典的“一路回車大法”。下面簡單介紹一下模擬鍵盤操作的方法。
Send
這個是最直接的方法,就是模擬用戶按鍵行為,直接發送鍵擊命令,用法請參考官方文檔,在此不予說明。
最簡單的應用――按回車:
AHK:
Run, Control Sysdm.cpl
WinWait, 系統屬性
Send, {Enter}
AU3:
Run("Control Sysdm.cpl")
WinWait("系統屬性")
Send("{Enter}")
常見的組合鍵――Alt+X / Ctrl+N等等,在安裝軟件的時候經常會有提供一個按鈕“下一步(N)”,表示按下Alt+N即可觸發等同於點擊該按鈕的效果,其它的可觸類旁通。以打開記事本窗口的“文件”菜單為例:
AHK:
Run, Notepad
WinWait, 無標題 - 記事本
WinActivate, 無標題 - 記事本
WinWaitActive, 無標題 - 記事本
Send, !f
AU3:
Run("Notepad")
WinWait("無標題 - 記事本")
WinActivate("無標題 - 記事本")
WinWaitActive("無標題 - 記事本")
Send("!f")
五、自動化操作輕松入門系列5
yonken
控件操作
然而,在真正實現自動化時僅靠上面的技術往往難以達到預期目的。下面開始進入最為重要的控件操作。
1、設置文本
在安裝軟件的過程中用戶往往需要提供一些必需信息,比如安裝目錄。很多用戶並不喜歡把軟件安裝到默認的C盤而更願意把它們安裝到別的地方,那么腳本究竟提供了什么方法能讓我們修改如下圖所示的路徑呢?
我們先用上文中提到的AutoIt3 Window Spy 或 AutoIt Window Info 來獲得這個路徑的編輯框的信息,假設這個窗口的標題為Setup foobar,該路徑編輯框的類名是Edit1,而我們需要把它改成“D:\foobar2000”,接下來就可以使用下列命令/函數來設置它的文本了:
AHK:
ControlSetText [, 目標控件, 新文本, 窗口標題, 窗口文本, 排除標題, 排除文本]
AU3:
ControlSetText ( "窗口標題", "窗口文本", 控件ID, "新文本")
具體用法如下:
【示例5.1.1】
AHK:
ControlSetText, Edit1, D:\foobar2000, Setup foobar
AU3:
ControlSetText("Setup foobar", "", "Edit1", "D:\foobar2000")
2、選中和取消選中單選框和復選框項目
有時程序為了滿足用戶的個性化設置而需要用戶提供更多的信息,我們經常會遇到這樣的情況:
如何保證選中所需項目並取消某些項目呢?
下面先來介紹AHK和AU3中用來對控件進行各種屬性設置的命令/函數:
AHK:
Control [, 命令, 值, 目標控件, 窗口標題, 窗口文本, 排除標題, 排除文本]
AU3:
ControlCommand ( "窗口標題", "窗口文本", 控件ID, "命令", "選項")
其中,“命令”就是讓我們指定要進行何種設置的參數。對這些單選框/復選框按鈕來說,適用的命令是“Check”和“UnCheck”。
假設這個窗口的標題是為Setup foobar,我們打算進行下來操作:
選中它的“桌面”復選框(Button5)、取消選中“快速啟動欄”復選框(Button7);
選中“0.7x”單選框(Button14)。
那么具體的用法示例如下:
【示例5.1.2】
AHK:
Control, Check, , Button5, foobar
Control, UnCheck, , Button7, foobar
Control, Check, , Button14, foobar
AU3:
ControlCommand("foobar", "", "Button5", "Check", "")
ControlCommand("foobar", "", "Button7", "UnCheck", "")
ControlCommand("foobar", "", "Button14", "Check", "")
2、選擇下拉列表的項目
相信你肯定遇到過下面這種情況:
問題又來了:如何選中自己需要的項目?
答案仍是使用上面提到的命令/函數。對這種控件而言,AHK適用的命令是“Choose, N”和“ChooseString, String”,分別表示選中第N個項目和選中與字符串String匹配的項目;而AU3適用的命令則是“SetCurrentSelection, N”和“SelectString, String”,分別表示選中第N+1(注意是從零開始表示!)個項目和選中與字符串String匹配的項目。
假設我們要選中第五個項目“簡體中文”,那么具體的用法示例如下:
【示例5.1.3】
AHK:
Control, Choose, 5, ComboBox1, Installer
Control, ChooseString, 簡體中文, ComboBox1, Installer
AU3:
ControlCommand("Installer", "", "ComboBox1", "SetCurrentSelection", 4)
ControlCommand("Installer", "", "ComboBox1", "SelectString", "簡體中文")