Page 1 of 2

Wait until several processes have ended

Posted: 30 May 2012 06:47
by SmurfCowboyJoe
Hallo,

in my batch script I start some processes with 'start xyz abc' in a for loop. So, they are all running concurrently. What I want to do is that my batch script does not continue until these processes have been ended. Is there any way in batch to achieve this?

Thx a lot
SmurfCowboyJoe

Re: Wait until several processes have ended

Posted: 30 May 2012 07:34
by foxidrive
use the /wait switch.

start "" /w "c:\program files\folder\file.exe"


This will show you the switches:
start /?


If you start several processes at once then you cannot use the /wait switch, or you can run them in sequence.

Re: Wait until several processes have ended

Posted: 30 May 2012 07:44
by SmurfCowboyJoe
Yes, I need to start them at once. This is the problem. Is there a way to use takslist or something to check whether a the process is still running?

Re: Wait until several processes have ended

Posted: 30 May 2012 08:01
by foxidrive
SmurfCowboyJoe wrote:Yes, I need to start them at once. This is the problem. Is there a way to use takslist or something to check whether a the process is still running?


This sort of code should work:



within your loop

start "" "exename1.exe"
start "" "exename2.exe"
start "" "exename3.exe"
start "" "exename4.exe"
call :delay
your further commands here
)


goto :EOF
:delay
set "var="
tasklist /FI "imagename eq exename1.exe">nul &&set var=1
tasklist /FI "imagename eq exename2.exe">nul &&set var=1
tasklist /FI "imagename eq exename3.exe">nul &&set var=1
tasklist /FI "imagename eq exename4.exe">nul &&set var=1
if defined var ping -n 60 localhost>nul & goto :delay

Re: Wait until several processes have ended

Posted: 30 May 2012 08:05
by Squashman
I was looking at using TASKLIST and piping it to the FINDSTR command and then doing conditional execution based on that output with the double ampersand but I am getting some really weird results on my machine with that code.

I have notepad and another program called DeskPins running on my system right now. And for some reason it will not always find them or it will only find one of them. Even when I just try to find one of them it seems to not even find it. I have never seen this happen before so I don't know what is going on with my machine right now.

Code: Select all

H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"
notepad.exe                 5864 Console                 0      3,912 K

H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"
                                                                               notepad.exe                 5864 Console                 0      3,912
H:\>tasklist /NH |findstr /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe"
notepad.exe                 5864 Console                 0      3,912 K

H:\>tasklist /NH |findstr /C:"notepad.exe"
notepad.exe                 5864 Console                 0      3,912 K

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"
notepad.exe                 5864 Console                 0      3,912 K

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe"
DeskPins.exe                2908 Console                 0        420 K

H:\>tasklist /NH |findstr /C:"DeskPins.exe" /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe" /C:"notepad.exe"
DeskPins.exe                2908 Console                 0        420 K

H:\>tasklist /NH |findstr /C:"DeskPins.exe" /C:"notepad.exe"

H:\>tasklist /NH |findstr /C:"DeskPins.exe" /C:"notepad.exe"
notepad.exe                 5864 Console                 0      3,912 K

H:\>


Ultimately I thought you would be able to do something like this.

Code: Select all

start "" "notepad.exe"
start "" "DeskPins.exe"
:Loop
tasklist /NH |findstr /C:"notepad.exe" /C:"DeskPins.exe" &&GOTO :Loop

Re: Wait until several processes have ended

Posted: 30 May 2012 08:11
by foxidrive
I read here in Dostips that when using the /c: switch more than once that you have to also use the /i case insensitive switch, because of a bug.


EDIT:

Yes, your technique works well too squashman.

Code: Select all

@echo off
start "" "notepad.exe"
start "" "calc.exe"
:Loop
tasklist /NH |findstr /i /C:"notepad.exe" /C:"calc.exe" >nul && (
ping -n 60 localhost>nul
GOTO :Loop
)
pause

Re: Wait until several processes have ended

Posted: 30 May 2012 08:29
by SmurfCowboyJoe
Thx a lot. But there is a another little problem. The process I start, is a java application. Therefore, in the tasklist there are several java.exe entries show but I dont know which of them has been started by me. I need a way to distinguish started process in my batch script and processes that have been executed from somewhere else.

Re: Wait until several processes have ended

Posted: 30 May 2012 09:42
by Fawers
SmurfCowboyJoe wrote:Thx a lot. But there is a another little problem. The process I start, is a java application. Therefore, in the tasklist there are several java.exe entries show but I dont know which of them has been started by me. I need a way to distinguish started process in my batch script and processes that have been executed from somewhere else.

It's probably the last one. TASKLIST lists processes in order of execution. I mean, at least on my machine it does.

Try it. Run notepad.exe, or cmd.exe, or the Java application itself, and then run tasklist.

Re: Wait until several processes have ended

Posted: 30 May 2012 09:59
by Squashman
SmurfCowboyJoe wrote:Thx a lot. But there is a another little problem. The process I start, is a java application. Therefore, in the tasklist there are several java.exe entries show but I dont know which of them has been started by me. I need a way to distinguish started process in my batch script and processes that have been executed from somewhere else.

Try and be more specific on your requirements from now on.

Re: Wait until several processes have ended

Posted: 30 May 2012 10:00
by Squashman
foxidrive wrote:I read here in Dostips that when using the /c: switch more than once that you have to also use the /i case insensitive switch, because of a bug.


EDIT:

Yes, your technique works well too squashman.

Code: Select all

@echo off
start "" "notepad.exe"
start "" "calc.exe"
:Loop
tasklist /NH |findstr /i /C:"notepad.exe" /C:"calc.exe" >nul && (
ping -n 60 localhost>nul
GOTO :Loop
)
pause

Good Idea on putting the delay in there.

Re: Wait until several processes have ended

Posted: 30 May 2012 10:04
by Squashman

Code: Select all

tasklist /NH /FI "username eq Squashman"

Re: Wait until several processes have ended

Posted: 30 May 2012 10:12
by Squashman
Another option would be to use the /V switch with the TASKLIST command and then pipe it to Findstr and have Findstr look for the Specific Window Titles.

Re: Wait until several processes have ended

Posted: 30 May 2012 15:20
by Aacini
SmurfCowboyJoe wrote:in my batch script I start some processes with 'start xyz abc' in a for loop.
You don't said the way you use the for loop to start the processes, so I assume there are several differently named data files that are started with the same application.

You may use a small Batch file instead to directly start the application; this way, the Batch file: 1- Create a file with unique name that is used as a flag, 2- Start the application, and 3- Delete the flag file. For example, instead of:

Code: Select all

for %%f in (*.xyz) do start "%%f" application %%f abc
you may use:

Code: Select all

for %%f in (*.xyz) do start "%%f" starter.bat %%f abc
so Starter.bat is:

Code: Select all

@echo off
echo Anything > %1.flg
application %1 %2
del %1.flg

This way, to wait for all concurrent processes to end:

Code: Select all

@echo off
for %%f in (*.xyz) do start "%%f" starter.bat %%f abc
:wait
ping -n 60 localhost>nul
if exist *.flg goto wait
pause

Re: Wait until several processes have ended

Posted: 31 May 2012 05:43
by dbenham
@Aacini - I was thinking of posting the same solution, but you beat me to it. :D

One slight potential problem:

It takes time for the STARTed processes to initialize. I believe your master script could potentially begin checking for .flg files before the STARTed processes have finished initializing, so it could exit prematurely.

This could easily be solved by having each starter.bat write two flags: xxx.started and xxx.running

Then you would have two conditions to check to see if all of the processes have completed.

1) count the number of xxx.started files and confirm it matches the number of started processes
2) verify there are no xxx.running files

Once both conditions are true, the master script can delete all of the xxx.started files and exit.


Dave Benham

Re: Wait until several processes have ended

Posted: 31 May 2012 11:32
by Aacini
@dbenham: Another possible, easier solution is to create the .flg files in the master script and let the starter.bat file just delete they:

Code: Select all

@echo off
for %%f in (*.xyz) do (
   echo Anything > %%f.flg
   start "%%f" starter.bat %%f abc
)
:wait
ping -n 60 localhost>nul
if exist *.flg goto wait
pause


Antonio