I once used this code (a modified snippet by ...er, I forgot
):
alias isrun {
if (($isid) && ($1 != $null)) {
if ($com(isrun_a)) { comclose isrun_a }
if ($com(isrun_b)) { comclose isrun_b }
.comopen isrun_a WbemScripting.SWbemLocator
if (!$com(isrun_a)) { return }
.comclose isrun_a $com(isrun_a,ConnectServer,3,dispatch* isrun_b)
if (!$com(isrun_b)) { return }
.comclose isrun_b $com(isrun_b,ExecQuery,3,string,SELECT ProcessId FROM Win32_Process WHERE Name = $qt($1) $+ ,dispatch* isrun_a)
if (!$com(isrun_a)) { return }
noop $com(isrun_a,Count,3)
var %return = $iif(($com(isrun_a).result),$true,$false)
.comclose isrun_a
return %return
}
}
Example:
//echo -ag $isrun(cmd.exe) | run cmd.exe | echo -a $isrun(cmd.exe)
For a "wait till process x is no longer running", you could do something like:
alias delayrun {
; possible /run switches
var %switches = $iif(($left($$1,1) == -),$1)
if (%switches) { tokenize 32 $2- }
; possibly quoted process (file name)
var %proc = $iif($regex($1-,/^"([^"]+)"/),$regml(1),$1)
; process not running: issue /run command
if (!$isrun(%proc)) { !run %switches $1- }
; process currently running: start retry timer (500 ms delay)
else { $+(.timer.delayrun.,%proc,$ticks) -mdo 1 500 delayrun $safe2(%switches $1-) }
}
; prevent evaluation of the command passed in the timer
alias -l safe2 { bset -t &a 1 $1 | return $!regsubex(safe2, $bvar(&a,1-) ,/(\d+)(?: |$)/g,$chr(\1)) }
Example:
//var %c = cmd.exe /q /c ipconfig /all | run %c | run %c
(two instances of the command shell should pop up "together")
vs.
//var %c = cmd.exe /q /c ipconfig /all | delayrun %c | delayrun %c
(the second window should pop up after the first closed)
Note that the more /delayrun commands you queue, the more overhead the individual timers will create. If you want to queue *lots* of commands for some process, better use one timer per process name that if the process closed is calling some /next.run alias (which in turn manages your queue) or sends a /signal or the like.