首页 > 解决方案 > 让 AutoIT 等到 Audacity 完成命令

问题描述

我有一个脚本,我想用它来自动化 Audacity 中的流程。我已经设置好了,所以我想在 Audacity 中执行的所有功能都是键盘快捷键(因为我不认为 Audacity 使用标准的窗口菜单,就像是必需的WinMenuSelectItem())换句话说,我的整个代码由Send()命令的多个实例组成. 问题是,AutoIT 执行代码的速度太快了。我尝试过使用WinWait(),但这些过程需要不同的时间。我也试过了ShellExecuteWait()RunWait()有没有办法让它等到程序没有做某事,然后执行我的发送命令?这是我的一些代码

Run("C:\Program Files (x86)\Audacity\audacity.exe")
; wait until it's active
WinWaitActive("Audacity")

; get the dialogue box to go away
Send("{ENTER}")
RunWait("Audacity")

; open files
Send("^o")
RunWait("Audacity")

; open the certain file & press enter
Send("test.wav")
RunWait("Audacity")
Send("{ENTER}")
RunWait("Audacity")

; select left boundary of silence period
Send("[")
RunWait("Audacity")
Send("000000100{ENTER}")
RunWait("Audacity")

; select right boundary of silence period
Send("]")
RunWait("Audacity")
Send("200000000{ENTER}")
RunWait("Audacity")

标签: autoitaudacity

解决方案


; Use for debugging issues. Systray icon show current line.
Opt('TrayIconDebug', 1)

; Delay default: 250s
Opt('WinWaitDelay', 400)

; Delay default: 5s
Opt('SendKeyDelay', 100)

; Path of the wav file.
$sInFile = @WorkingDir & '\test.wav'

; Optional permanent change of splash screen setting.
_SplashScreen(True)

; Run Audacity and argument of the wav file.
$iPid = Run('"C:\Program Files (x86)\Audacity\audacity.exe" "' & $sInFile & '"')

; Check if Run Audacity failed.
If @error Then
    MsgBox(0x40030, @ScriptName, 'Failed to run Audacity')
    Exit 1
EndIf

; Wait for main window to get handle. Title is the filename with no extension.
$hMainWindow = WinWait('[TITLE:test; CLASS:wxWindowNR]', '', 10)

; Check allowed timeout of window.
If Not $hMainWindow Then
    MsgBox(0x40030, @ScriptName, 'Audacity window not detected.')
    Exit 1
EndIf

; If splash screen setting not 0 then handle the window.
If _SplashScreen() Then
    AdlibRegister('_WelcomeWindow')
    WinWait('Welcome to Audacity', '', 3)
    AdlibUnRegister('_WelcomeWindow')
EndIf

; Send '[' to main window to trigger Left Boundary window.
ControlSend($hMainWindow, '', '', '[')

; Get handle of Left Boundary window.
$hMsgWindow = WinWait('Set Left Selection Boundary', '', 5)

; Check allowed timeout of window.
If Not $hMsgWindow Then
    MsgBox(0x40030, @ScriptName, 'Selection Boundary window not detected.')
    Exit 1
EndIf

; Activate window, set time and click OK.
If WinActivate($hMsgWindow) Then
    ControlSend($hMsgWindow, '', 'wxWindowNR1', '{LEFT 3}1'); 1000
    ControlClick($hMsgWindow, '', 'Button2'); OK
EndIf

; Send ']' to main window to trigger Right Boundary window.
ControlSend($hMainWindow, '', '', ']')

; Get handle of Right Boundary window.
$hMsgWindow = WinWait('Set Right Selection Boundary', '', 5)

; Check allowed timeout of window.
If Not $hMsgWindow Then
    MsgBox(0x40030, @ScriptName, 'Selection Boundary window not detected.')
    Exit 1
EndIf

; Activate window, set time and click OK.
If WinActivate($hMsgWindow) Then
    ; Audacity shows 1000 and focus is on the 1st non zero digit which is 1.
    ControlSend($hMsgWindow, '', 'wxWindowNR1', '2'); 2000
    ControlClick($hMsgWindow, '', 'Button2'); OK
EndIf

; More code to do.
Sleep(1000)

MsgBox(0x40040, @ScriptName, 'End of automation.' & @CRLF & @CRLF & _
     'You can close Audacity to finish.')

; Wait for Audacity process to close.
ProcessWaitClose($iPid)

Exit

Func _WelcomeWindow()
    ; Used by AdlibRegister to handle the Welcome window.

    ; Welcome window hides if closed so need to check if exist and is visible (2).
    If WinExists('Welcome to Audacity') Then
        If BitAND(WinGetState('Welcome to Audacity'), 2) Then
            WinClose('Welcome to Audacity')
        Else
            AdlibUnRegister('_WelcomeWindow')
        EndIf
    EndIf
EndFunc

Func _SplashScreen($bDisable = False)
    ; Write to audacity.cfg to disable splash screen.
    Local $sIniFile = @AppDataDir & '\Audacity\audacity.cfg'

    If IniRead($sIniFile, 'GUI', 'ShowSplashScreen', '1') = '1' Then
        If $bDisable Then
            ; Return 1 if ini file change is success.
            If IniWrite($sIniFile, 'GUI', 'ShowSplashScreen', '0') Then
                Return 1
            EndIf
        Else
            ; Return 1 if check for splash screen is enabled.
            Return 1
        EndIf
    EndIf
EndFunc

Opt()用于减慢窗口和发送的等待。还添加Opt('TrayIconDebug', 1)了调试,但如果脚本被认为是好的,那么你可以删除它Opt()

ControlSend()用于代替 目标窗口和基于标题、文本等的控件。Send()尽管添加了延迟以演示用法,但不需要延迟,尽管 Audacity 可能难以跟上 AutoIt 可以自动化的速度。如果可能,建议使用自动化功能。ControlSend()Opt()Control*()

将窗口句柄存储在变量中有助于节省代码中重新键入的标题。WinWait()返回一个理想的窗口句柄,如果使用超时参数,则 0 表示未找到窗口,因此可以中止自动化。

主窗口的 Classname 本身是不够的,因为 Audacity 创建了许多具有相同 Classname 的不可见窗口。因此,可能还需要使用标题。标题可以单独使用,但文件名有时可能不是唯一的。有关用法,请参阅窗口标题和高级文本。

WinActivate()在边界窗口上使用,尽管它可能不需要,因为control*()通常不需要活动窗口。相比之下,标准 Msgbox 可能需要处于活动状态才能接受发送给它们的消息。

ShellExecuteWait()并且RunWait()不利于自动化,因为它们会阻止脚本继续执行,直到执行的过程完成。所以使用ShellExecute()orRun()代替。重复使用RunWait("Audacity")似乎是不顾一切地纠正这种行为,尽管有缺陷。等待窗口出现是如何控制流程,然后是ControlCommand()可以检测控件状态等功能。

ControlClick()用于按钮。使用ClassnameButton2的 CtrlID,但如果脚本始终用于英语用户,那么您可以使用OK用于OK按钮的文本。

ProcessWaitClose($iPid)是可选的。在脚本退出之前等待程序自动退出有时很有用。

启动 Audacity 后,您在代码中评论“让对话框消失”。您可以更改对话框或首选项 -> 界面选项上的设置。建议禁用,因为这是继续处理的未来问题。我添加了一些代码来禁用 audacity.cfg文件中的设置。如果不喜欢禁用 _SplashScreen(True)或手动完成,则AdLibRegister('_WelcomeWindow')调用将处理关闭窗口。请注意,欢迎窗口不会关闭而是隐藏。

_SplashScreen(True)将启动画面设置更改0为禁用启动画面。

_SplashScreen(False)_SplashScreen()不更改设置。1如果启用了启动 else ,则调用返回0


推荐阅读