How To Wait As Long As A Program (And Its Sub Processes) Are Running?
Friday, 24. August 2007 0:10
Recently, some talented colleagues of Login Consultants and I worked out a robust batch subroutine that waits for the termination of a setup (or whatever) program including those processes that have been started by that program.
In most cases the START /WAIT command meets the requirement that is to stop batch processing as long as the (setup) program is running. For example, this works fine for MSI based installations. All you have to do is START /WAIT msiexec.exe … and you’re done. The same applies to other installer types like Inno, Wise, or NSIS.
But many InstallShield setups and proprietary setups (like the Oracle installer) do actually nothing more than to call a second process (javaw.exe in case of Oracle) and terminate immediately afterwards. Since START /WAIT does only watch over the specified program it would pass back script control to cmd.exe although the actual setup isn’t yet finished.
TASKLIST.EXE is an external command of Windows XP Professional, Windows Server 2003, and newer. It displays a list of processes and services with their Process ID (PID) for all tasks. Using filters you can query for a specific process.
The batch file below, Start-Wait.cmd, uses TASKLIST.EXE. Before actually starting the specified program Start-Wait.cmd gets the PIDs of all processes that have the same name like the specified sub process (for example javaw.exe). This step is important in order to make sure that the script later checks the correct sub process. Let’s say that you want the script to check javaw.exe as a sub process of the Oracle installer on a Citrix terminal server. Maybe at the same time you have started the Management Console (which is based on javaw.exe)… Got it? Talking of terminal servers: Start-Wait.cmd cuts TASKLIST.EXE‘s output down to the processes owned by the user who is executing the script. When done with making out the ignorable PIDs the script start the specified program. Afterwards it uses TASKLIST.EXE again in order to identify the PID of the specified sub process. Finally, the Start-Wait.cmd checks each 5 seconds if the process with that PID is still running.
@ECHO OFF :: NAME :: Start-Wait.cmd :: :: SYNOPSIS :: Suspend script activity as long as the specified program and its sub :: process are running :: :: SYNTAX :: Start-Wait program subprocess :: Start-Wait "program arguments" subprocess :: :: DETAILED DESCRIPTION :: The Start-Wait.cmd batch file suspends script activity as long as the :: specified program and its sub process are running. You can use it in a :: batch script to wait for a setup program to complete completely. :: :: AUTHOR :: Frank-Peter Schultze :: :: DATE :: 17:02 04.04.2008 SETLOCAL ENABLEDELAYEDEXPANSION IF "%1"=="/?" ( TYPE "%~f0" | findstr.exe /R "^:: " GOTO :END ) SET Program=%~1 IF NOT DEFINED Program ( ECHO %~n0 : Cannot bind argument to parameter 'Program' because it is empty. GOTO :END ) SET SubProcess=%2 IF NOT DEFINED SubProcess ( ECHO %~n0 : Cannot bind argument to parameter 'SubProcess' because it is empty. GOTO :END ) SET IGNOREPIDS= ::----- First, get all PIDs that we don't want to check later by mistake FOR /F "tokens=2 skip=3" %%i IN ( 'tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %SubProcess%"' ) DO ( SET IGNOREPIDS=!IGNOREPIDS! %%~i ) ::----- Start the program and wait for its termination START /WAIT %Program% ::----- Now, get the PID of the sub process that we need to check FOR /F "tokens=2 skip=3" %%i IN ( 'tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %SubProcess%"' ) DO ( ECHO #%IGNOREPIDS%# | find.exe "%%~i" >NUL || CALL :TASKWAIT %SubProcess% %%~i ) :END ENDLOCAL EXIT /B :: :TASKWAIT :: ECHO Sleep 5s . . . ping.exe -n 6 -w 1000 127.0.0.1 >NUL tasklist.exe /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "IMAGENAME eq %1" /FI "PID eq %2" 2>NUL | find.exe "%1" >NUL && GOTO %0 ECHO %1 stopped. EXIT /B
Category:Cmd.exe Shell, Scripting | Comment (0) | Author: Frank-Peter