让 AutoIT 等到 Audacity 完成命令

Making AutoIT wait until Audacity completes command

我有一个脚本,想用来在 Audacity 中自动执行流程。我设置了它,以便我想在 Audacity 中执行的所有功能都是键盘快捷键(因为我不认为 Audacity 使用 WinMenuSelectItem() 所需的标准 window 菜单)换句话说,我的整个代码由 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")
; 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() 用于减慢 windows 的等待和发送。 还添加了 Opt('TrayIconDebug', 1) 用于调试,如果 该脚本被认为是好的然后你可以删除 Opt().

使用

ControlSend() 而不是 Send() 作为 ControlSend() 基于标题、文本等的目标 windows 和控件。 Opt() 延迟不是必需的,但已添加到 演示用法,尽管 Audacity 可能会遇到困难 以跟上 AutoIt 可以自动化的速度。 如果可能,建议使用 Control*() 函数进行自动化。

在变量中存储 window 句柄有助于节省重新输入标题的时间 在代码中。 WinWait() returns 一个 window 手柄,这是理想的 如果使用超时参数,则 0 表示 window 不 发现可以中止自动化。

主要 window 的类名本身不够,因为 Audacity 创建了许多具有相同类名的不可见 windows。 因此,可能还需要使用标题。标题可以是 尽管以文件名命名,但单独使用有时可能不是唯一的。 请参阅 Window Titles and Text Advanced 了解用法。

WinActivate() 用于边界 windows 虽然它 可能不需要,因为 control*() 通常不需要活动 windows。相比之下,标准 Msgboxes 可能需要 主动接受发送给他们的消息。

ShellExecuteWait()RunWait() 不利于自动化 因为他们阻止脚本继续执行直到执行 过程已经完成。 因此,请改用 ShellExecute()Run()。 重复使用 RunWait("Audacity") 似乎 尽管有缺陷,但也许不顾一切地纠正这种行为。 等windows出现就是怎么控制流量然后 ControlCommand() 等函数可以检测控件的状态。

ControlClick()用在按钮上。 类名 Button2 的 CtrlID 被使用 始终适用于英语用户,那么您可以使用其中的文本 对于 OK 按钮将是 OK

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

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

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

_SplashScreen(False)_SplashScreen() 不更改设置。 如果启动启动则调用 returns 1 否则 0