In today’s small hack session the requirement sounds rather simple: Wait for a given process to exit and then exit the AutohotKey script itself – all while being non-blocking.
The most obvious choice would be a simple loop that checks whether the process still exists. This is also the implementation you will find when searching for this problem on the web. The drawback of this approach is the high cost in runtime, so that is no good; why would I want to burn CPU cycles constantly?
A much better way is to register a callback with Windows and have the operating system notify you once the process has exited.
#Requires AutoHotkey v2.0.2
#SingleInstance Force
DllCall("LoadLibrary", "Str", "Kernel32.dll")
ProcessExitCallback := CallbackCreate(OnProcessExit)
; Function to register a callback for process exit
RegisterForProcessExit(pid) {
; Open the process handle with SYNCHRONIZE access
hProcess := DllCall("OpenProcess", "UInt", 0x00100000, "Int", 0, "UInt", pid, "Ptr")
if (!hProcess) {
MsgBox("Failed to open process handle. Error: " DllCall("GetLastError"), "Error opening process handle", "OK IconX")
return
}
; Create a variable to hold the wait handle
waitHandle := 0
; Register the wait
success := DllCall("Kernel32.dll\RegisterWaitForSingleObject"
, "Ptr*", &waitHandle ; Output wait handle (mutable variable)
, "Ptr", hProcess ; The process handle
, "Ptr", ProcessExitCallback ; The callback function
, "Ptr", pid ; The parameter passed to the callback (PID)
, "UInt", 0xFFFFFFFF ; INFINITE wait time
, "UInt", 0x00000000) ; WT_EXECUTEONLYONCE
if (!success) {
MsgBox("Failed to register wait. Error: " DllCall("GetLastError"), "Error registering callback", "OK IconX")
DllCall("CloseHandle", "Ptr", hProcess)
return
}
}
; The callback function to execute when the process exits
OnProcessExit(param, TimerOrWaitFired) {
ExitApp(0)
}
; Main script execution
pid := ProcessExist("Notepad.exe") ; Replace with your target process name
if pid
RegisterForProcessExit(pid)
else
MsgBox("Notepad.exe is not running!", "Notepad", "OK IconX")
The callback approach has the advantage of being able to run in the background for a long time without noticeable performance impact.