AutoHotKey进程等待脚本优化:需兼顾进程启动与用户输入中断
Got it, let's sort out this script for you. The core issue with your original code is that Process, Wait blocks the script entirely when there's no timeout set—so it can't listen for user input at all. Plus, the A_TimeIdlePhysical check was backwards from what you needed. Here's how to fix it properly:
First: Check for Existing Process on Startup
First, we need to exit immediately if SomeProcess.exe is already running when the script starts. That's straightforward:
; Exit right away if the target process is already running Process, Exist, SomeProcess.exe if (ErrorLevel) { ExitApp }
Option 1: Listen for Any User Input (Keyboard + Mouse)
This solution captures any keyboard press or mouse click to terminate the wait, while checking for the process at regular intervals. It uses message listeners to catch user input events:
; Initial check as above Process, Exist, SomeProcess.exe if (ErrorLevel) { ExitApp } ; Register listeners for common user input events OnMessage(0x0100, "OnUserInput") ; Catch keyboard key presses OnMessage(0x0201, "OnUserInput") ; Catch left mouse button down OnMessage(0x0205, "OnUserInput") ; Catch right mouse button down OnMessage(0x0203, "OnUserInput") ; Catch middle mouse button down ; Loop to check for process start with short timeouts Loop { ; Wait 100ms for the process to start (non-blocking enough to catch input) Process, Wait, SomeProcess.exe, 0.1 if (ErrorLevel) { ; Process started! Exit the script ExitApp } ; If user input is detected, OnUserInput will exit the script automatically } ; Triggered when any user input is detected OnUserInput() { ExitApp }
How This Works:
- The
OnMessagehooks listen for low-level keyboard and mouse events. Any input triggers theOnUserInputfunction, which immediately exits the script. - The
Process, Wait, , 0.1uses a 100ms timeout, so the script never blocks for long. Every 100ms, it checks if the process started—if not, it loops back and keeps listening for input.
Option 2: Keyboard-Only Input (Simpler)
If you only care about keyboard input (not mouse clicks), you can use the Input command instead of message listeners. This is more concise:
; Initial check Process, Exist, SomeProcess.exe if (ErrorLevel) { ExitApp } Loop { ; Check if the process has started Process, Exist, SomeProcess.exe if (ErrorLevel) { ExitApp } ; Wait 100ms for keyboard input; if none, loop again Input, , T0.1 V ; If input was detected (not just a timeout), exit if (ErrorLevel != "Timeout") { ExitApp } }
Why Your Original Code Failed
Your original line while (A_TimeIdlePhysical > 100) { Process, Wait, SomeProcess.exe } had two big issues:
Process, Waitwith no timeout blocks the script indefinitely—so it can't respond to any user input until the process starts.A_TimeIdlePhysical > 100checks if the system has been idle for over 100ms, which is the opposite of what you wanted (you want to stop waiting when the user does input something).
内容的提问来源于stack exchange,提问作者Россарх

