學會一門腳本語言對於日常使用操作系統有很大的幫助,如果是跨平台腳本,目前首選python;但是如果只是針對Windows,那么AutoIt是目前最好的選擇之一,雖然不如Windows原生支持的VBScript或bat文件那么方便,但是AI3的強大之處在於它是模擬人與GUI交互的過程的自動化腳本語言——換言之,只要人可以手工完成的任務幾乎都可以用AI3模擬完成,而不論你想操作的對象是否開放了對應的API。AI3整體語法特征是basic風格的,學習起來很容易上手,而且AI3可以直接調用winapi,與com交互,功能多多,擴展性好,學習的價值還是很大的。缺點是不跨平台,編譯速度很慢。最后吐槽一下AI3同時是人工少女的縮寫=,=
以下是入門知識的簡單總結:
變量:類似VBS,動態變量類型,不區分大小寫,用關鍵字Dim, Local, Global聲明,Dim會復用已存在的全局變量。變量必須以$開頭。
常量:常量以const關鍵字聲明,初始化可以用Enum關鍵字。
運算符:復合運算符同C,其他大體類似VB:字符串連接用&,計算冪次用^,不等於是<>,數值和不區分大小寫的字符串比較相等用=,區分用==,邏輯運算用AND,OR和NOT。優先級類似於C語言。
常用宏:可以直接獲得某些特殊字符串,例如文件所在路徑等。這些宏以@開頭,可以直接當作字符串在程序中使用。
流程控制:同VB的語法風格。if…then…elseif..then…else…endif;select xxx…case xxx…case else…endselect和swith…case語句(前者用於多變量,后者用於單變量);for..to..step…next;while…wend;do…until…;關鍵字exitloop(n=1)用於跳出第n層循環
函數:函數以關鍵字Func聲明,以Return返回值,以EndFunc結束。默認是傳值,加上關鍵字byref用來傳引用。
注釋:分號后面的同行字都是注釋。
窗口:AI3直接提供了GUI創建。使用GUIcreate創建新窗口,GUISetState設置窗口風格,GUIGetMsg捕獲消息,GUIDelete刪除窗口。窗口處理方式有同步和異步兩種。異步主要指的是event模式。
例程:
- Global Const $GUI_EVENT_CLOSE = -3 ; 窗口關閉消息的值
- Opt ( "GUIOnEventMode" , 1 ) ; 開啟 Event 模式
- GUICreate ( " 我的第一個窗口 " ) ; 創建一個居中顯示的 GUI 窗口
- GUISetOnEvent ($GUI_EVENT_CLOSE, "main" ) ; 注冊關閉消息到自定義函數 main 里面進行處理
- $Input = GUICtrlCreateInput ( "1111" , 10, 35, 300, 20)
- $btn = GUICtrlCreateButton ( " 讀取輸入框 " , 40, 75, 90, 20)
- GUICtrlSetOnEvent ($btn, "main" ) ; 注冊按鈕點擊消息到自定義函數 main 里面進行處理
- GUISetState ( @SW_SHOW ) ; 顯示一個空白的窗口
- While 1 ; 死循環,保證腳本不會退出
- GUISetBkColor ( RandomColor () ) ; 修改窗口背景顏色
- Sleep (3000) ; 睡眠 3 秒
- WEnd
- Func main()
- Switch @GUI_CtrlId ; 根據宏 @GUI_CtrlId 來判斷消息
- Case $GUI_EVENT_CLOSE
- Exit
- Case $btn
- $D = GUICtrlRead ($Input) ; 讀取輸入框數據
- MsgBox ( 0 , " 輸入框的數據 " , $D)
- EndSwitch
- EndFunc
- Func RandomColor ()
- Return "0x" & Hex ( Random (0, 255, 1), 2) & Hex ( Random (0, 255, 1), 2) & Hex ( Random (0, 255, 1), 2)
- EndFunc ; 產生一個隨機的 RGB 顏色值
注意第3行開啟了event模式,第8行設置回調函數。11-14行是個死循環,每隔3秒改變一次窗口的背景色;16-28時注冊的回調函數,用來處理消息循環。26-28用來生成隨機的RGB顏色。
GUI創建顯然不是AI3的強項,因此這里只是簡單提供了對話框窗口的創建方法,和消息循環,消息映射的一些簡單實現。這些概念和win32大致相同。
字符串處理:對於腳本語言,字符串處理一般都是原生支持的。AI3壓根沒有類庫,所以必然也是原生支持的。字符串處理大致同VBS,單引號和雙引號等價。常用函數:
Stringlen, stringleft, stringright, stringmid, stringtrimleft, stringtrimright; stringreplace; stringsplit(返回一個序列,同python的split()方法。
正則表達式:驗證使用stringRegExp,驗證@error;在stringRegExp的第三個參數中指定2,會返回匹配的數組;使用stringRegExpReplace用來正則替換。
變量轉換:類似python,使用Ptr轉化為指針,HWND轉化為句柄,INT轉換為整數,字符串和編碼互轉:stringtobinary和binarytostring。
數組:AI仍然是舊式的basic風格,因此這里仍然是數組而不是序列。這里不必做太多解釋,注意Ubound函數可以用來取得數組的維數,Redim可以用來調整數組的大小(即重新聲明)。
注冊表讀取:因為AI3不是跨平台的,所以有些很深入的操作也被簡單集成成為函數了。操作注冊表的函數主要有:
RegRead用來讀取鍵值;RegEnumVal用來讀取鍵名下的所有鍵值,RegEnumKey用來讀取鍵名下所有子鍵名稱。
RegWrite用來寫入鍵值;RegDelete用來刪除鍵值。
文件IO:這里的文件指的是普通的文件,不是指文件流(包括設備)。主要包括以下函數:
Ini配置文件:寫腳本時最常用到的玩意。主要是Iniread, iniwrite和Inidelete。批量處理一個段使用IniReadSection,獲得所有段名使用iniReadSectionNames。
文本文件:FileOpen、FileClose、FileWrite、FileWriteLine、FileRead、FileReadLine
二進制文件:函數同文本文件,不過使用了不同的打開模式。
所有文件:filedelete、removedir、filemove、filecopy
進程管理:進程管理也是腳本最常用的操作之一。AI3內置了常用的相關函數:
ProcessList函數用來枚舉所有進程的列表;processwait用來等待進程出現,ProcessWaitClose用來等待進程結束;關閉進程用processclose。更復雜的操作需要調用系統的API來實現。
運行文件:Run,RunWait,RunAs,RunAsWait,ShellExecute,ShellExcuteWait。含有As的可以以其他用戶運行文件,含有wait的會阻塞進程直到該程序結束。以上只能運行可執行文件(EXE \COM 或 PIF),如果是批處理文件(.bat,.vbs),需要在文件路徑前加上解釋文件的路徑。ShellExecute可以執行任意文件。
窗口管理:winList會返回所有窗口列表(二維數組,句柄和標題);WinWait等待窗口,Winclose關閉窗口,參數可以使用窗口名稱或者窗口句柄。窗口自動化操作時AI3的特色,包括以下函數:
使用send和controlsend函數發送按鍵,后者用於后台。
控件控制(多用於自動安裝):ControlClick 、 ControlSetText 、 ControlCommand。
定時器:AdlibRegister 用來注冊定時器, AdlibUnRegister 用來釋放定時器。同時也可以使用API中的定時器。
COM調用:類似於Vbs,AI3也可以調用COM接口。使用CreateObject創建對象,然后調用對象的方法即可,大體方法也和vbs沒啥區別。錯誤處理使用ObjEvent注冊回調函數。
DLL調用:主要就是DllOpen,DLLCall和DllClose三個函數。
結構:AI3不支持結構,所有與C api交互結構數據的方法在於使用幾個函數:DllStructCreate 、 DllStructGetData 、 DllStructGetPtr 、 DllStructGetSize 、 DllStructSetData,很容易顧名思義。
Socket編程:為了方便socket編程,AI3直接封裝了winsock的相關接口,主要包括:TCPStartup(),TCPListen,TCPAccept,TCPRecv, TCPSend, TCPshutdown, TCPconnect。
數據庫編程:可以使用類似vbs的方法管理數據庫。這條和socket編程一樣,都不是AI3的強項,建議還是用python這種強大的腳本語言更適合。這里不再描述。
最后寫個小程序,夜里掛迅雷,有時候速度會變得很慢甚至變成0,這時候只要暫停並重新開始速度就上去了。這點可以用AI3來模擬實現,代碼如下(不正確,待修改):
#region ;**** 參數創建於 ACNWrapper_GUI ****
#PRE_Outfile_x64=C:\Users\Terran\Desktop\Temp\ThunderControl.exe
#PRE_Res_Fileversion=0.0.0.0
#PRE_Res_Fileversion_AutoIncrement=y
#PRE_Run_Tidy=y
#Obfuscator_Parameters= /sci 1/striponly
#endregion ;**** 參數創建於 ACNWrapper_GUI ****
;Auto pause and restart tasks in thunder every 30min
TraySetIcon("D:\Program Files (x86)\Thunder Network\Thunder\Program\SaveAs.exe")
TrayTip("Thunder watcher", "迅雷監控輔助程序已啟動", 10, 1)
AutoItSetOption("WinTitleMatchMode", 4)
$waitTime = ProcessWait("Thunder.exe", 3000)
If $waitTime = 0 Then _Exit()
TrayTip("Thunder watcher", "迅雷已啟動", 10, 1)
Const $timeInternal = 30 * 60 * 1000
While ProcessExists("Thunder.exe")
$aTitle = _show()
If $aTitle <> 0 Then
;MsgBox(1, "Debug", WinGetTitle($aTitle)
$result = WinWaitActive($aTitle, 9000)
If $result = 0 Then _Exit()
Send("{F9}")
Sleep(5000)
Send("{F8}")
Sleep(5000)
;WinSetState($aTitle, "", @SW_HIDE)
Sleep($timeInternal)
Else
MsgBox(1, "警告", "迅雷窗口未激活,即將退出", 5)
Exit
EndIf
WEnd
TrayTip("Thunder watcher", "迅雷監控輔助程序已退出", 10, 1)
Exit
Func _show()
Sleep(5000)
$handle = WinGetHandle("[CLASS:XLUEFrameHostWnd]")
If @error = 1 Or $handle = "" Then
MsgBox(1, "警告", "未發現指定窗口", 5)
Exit
EndIf
WinSetState($handle, "", @SW_SHOW)
WinActivate($handle, "")
Return $handle
EndFunc ;==>_show
Func _Exit()
MsgBox(1, "出錯了~~", "程序即將退出", 5)
Exit
EndFunc ;==>_Exit
還有個以前寫的小東西,參考了別人的作品。作用是在取消VMvare那么多服務的自啟動,轉而在需要的時候再啟動服務,然后在關閉程序后自動停止那些服務。
首先設置這幾個服務為手頭啟動。腳本內容:
#RequireAdmin
#Region ;**** 參數創建於 ACNWrapper_GUI ****
#PRE_Icon=D:\Program Files (x86)\VMplayer\vmplayer.exe
#PRE_Outfile=F:\SysBack\win7\vmplayer.exe
#PRE_Outfile_x64=F:\SysBack\win7\vmplayerx64.exe
#PRE_UseX64=n
#PRE_Res_Comment=自動按需開啟關閉AI3 VMware服務及網卡資源。
#PRE_Res_Fileversion=V1.00
#EndRegion ;**** 參數創建於 ACNWrapper_GUI ****
TraySetIcon("D:\Program Files (x86)\VMplayer\ico\config.ico")
TrayTip("VMWare", "啟動服務"VMware Authorization Service"", 10, 1)
RunWait(@ComSpec & " /c " & "net start VMAuthdService", "", @SW_HIDE)
TrayTip("VMWare", "啟動服務"VMware DHCP Service"", 10, 1)
RunWait(@ComSpec & " /c " & "net start VMnetDHCP", "", @SW_HIDE)
TrayTip("VMWare", "啟動服務"VMware NAT Service"", 10, 1)
RunWait(@ComSpec & " /c " & 'net start "VMware NAT Service"', "", @SW_HIDE)
TrayTip("VMWare", "啟動服務"VMUSBArbService"", 10, 1)
RunWait(@ComSpec & " /c " & "net start VMUSBArbService", "", @SW_HIDE)
TrayTip("VMWare", "啟動連接"VMware Network Adapter VMnet1"", 10, 1)
RunWait("devcon.exe enable *vmnetadapter1", "", @SW_HIDE)
TrayTip("VMWare", "啟動連接"VMware Network Adapter VMnet8"", 10, 1)
RunWait("devcon.exe enable *vmnetadapter8", "", @SW_HIDE)
TrayTip("VMWare", "", 10, 1)
RunWait("D:\Program Files (x86)\VMplayer\vmplayer.exe")
TrayTip("VMWare", "停止服務"VMware Authorization Service"", 10, 1)
RunWait(@ComSpec & " /c " & "net stop VMAuthdService", "", @SW_HIDE)
TrayTip("VMWare", "停止服務"VMware DHCP Service"", 10, 1)
RunWait(@ComSpec & " /c " & "net stop VMnetDHCP", "", @SW_HIDE)
TrayTip("VMWare", "停止服務"VMware NAT Service"", 10, 1)
RunWait(@ComSpec & " /c " & 'net stop "VMware NAT Service"', "", @SW_HIDE)
TrayTip("VMWare", "停止服務"VMware VMUSBArbService"", 10, 1)
RunWait(@ComSpec & " /c " & "net stop VMUSBArbService", "", @SW_HIDE)
TrayTip("VMWare", "停止連接"VMware Network Adapter VMnet1"", 10, 1)
RunWait("devcon.exe disable *vmnetadapter1", "", @SW_HIDE)
TrayTip("VMWare", "停止連接"VMware Network Adapter VMnet8"", 10, 1)
RunWait("devcon.exe disable *vmnetadapter8", "", @SW_HIDE)