-1

I have this batch code and its working perfectly well, BUT: every line take ~60 seconds to execute and I'm wondering, if I could do this faster...

Also the if Statements.. I want to check, if every Window is closed, and if so, I want to execute something. But if at least one window is still open, then it should check it again.

:loop
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server1%" /FO Table') do set #1=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server2%" /FO Table') do set #2=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server3%" /FO Table') do set #3=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server4%" /FO Table') do set #4=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server5%" /FO Table') do set #5=%%i
for /f %%i in ('tasklist /v /fi "WINDOWTITLE eq %server6%" /FO Table') do set #6=%%i
if not %#1%==cmd.exe (
    if not %#2%==cmd.exe (
        if not %#3%==cmd.exe (
            if not %#4%==cmd.exe (
                if not %#5%==cmd.exe (
                    if not %#6%==cmd.exe (
                        goto backup
                    )
                )
            )
        )
    )
) else (
    echo back to loop
    goto openWindow
)
  • You need add some other information. Is not clear what you want to do... – Einstein1969 Apr 25 '21 at 19:44
  • 1
    I have 6 different named batch files open. Then I'm closing the windows with setkey... But I can't determine how long it will take before all windows are closed. And if every window is closed, it shall goto backup. if now it shall do checkk it again – Awesome Sounds Apr 25 '21 at 19:54
  • 4
    why do you need verbose mode? – Gerhard Apr 25 '21 at 19:54

4 Answers4

3

Let me suggest a slightly different approach. Instead of all those if statements, you can just loop whenever one of the tasks exist:

:wait
timeout 1 >nul
for %%a in (%server1% %server2% %server3% %server4% %server5% %server6%) do (
  tasklist /nh /fi "windowtitle eq %%a" |find "  " >nul && goto :wait
)
echo all closed.

or

setlocal enabledelayedexpansion
:wait
timeout 1 >nul
for /l %%a in (1,1,6) do (
  tasklist /nh /fi "windowtitle eq !server%%a!" |find "  " >nul && goto :wait
)
echo all closed.

Note: find " " looks for two consecutive spaces, not a TAB)

If you choose your window titles wisely, you don't even need a for loop:

:wait
timeout 1 >nul
tasklist /nh /fi "windowtitle eq MySubWindow*" |find "  " >nul && goto :wait
echo all closed.

where the window titles all start with a fixed string (MySubWindow here), like MySubWindow-1, MySubWindow-2 etc. (yes, tasklist is able to use a wildcard - but only at the end of the string). This is basically "if any window exists with a title that starts with MySubWindow then loop"

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Stephan, I see there are problems, if you want you can add my version here, I delete my answer. – Einstein1969 Apr 26 '21 at 11:54
  • No need to delete your answer. It's correct, it's not plagiarism (as you properly declared the source), it has a useful addition, and it will inevitably generate reputation for you (especially when you add some explanation, how and why it's faster) – Stephan Apr 26 '21 at 12:15
2

little optimization of Stephan answer.

This execute faster.

:wait
timeout 1 >nul
for %%a in (%server1% %server2% %server3% %server4% %server5% %server6%) do (
  if not defined v%%a tasklist /nh /fi "windowtitle eq %%a" |find "  " >nul && goto :wait
  set v%%a=done
)
echo all closed.

Einstein1969
  • 317
  • 1
  • 13
  • Can you please explain your optimization? I see no logical or timing benefits at all. – Stephan Apr 26 '21 at 06:54
  • Correction: in some situations, this is indeed faster than mine (~150ms vs. ~750ms per pass in extreme) (not that it would matter, as OP is content with a `timeout 5` in the loop) – Stephan Apr 26 '21 at 07:56
  • I'm sorry stephan, I'm not feeling well today, as soon as I can I try to explain well. Can I ask you what tools did you use to measure times? – Einstein1969 Apr 26 '21 at 11:47
  • Don't worry. My first comment was based on "running the code In my head". After running it on a real computer, I realized, your modification is in fact useful. For measuring, I just used some `echo %time%` commands. Not very accurate, but sufficient to get a general idea of the speed. – Stephan Apr 26 '21 at 12:08
1

You have not explained how your 6 Batch files are "open", but if they are open via START command, then there is a much simpler way to do the same:

(
    start call batch1.bat
    start call batch2.bat
    start call batch3.bat
    start call batch4.bat
    start call batch5.bat
    start call batch6.bat
) | pause

echo All 6 Batch files are closed

The previous code run the 6 Batch files in parallel and then the control flow is stopped at the pause command. When all the 6 Batch files terminates, this program continue.

Note that there is not any Batch code that check if the procesess ends; this is done automatically by the Operating System. In this way, the wait state of this program does not waste any CPU time. For a further explanation, see this answer

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • hello Antonio, we haven't met for a long time, a warm greeting, thanks for this answer it is really useful and in the references there are many other alternatives. One question: Are there any technical details why you used pause instead of set /p? – Einstein1969 May 01 '21 at 09:30
  • Hi @Einstein1969, thanks for the greeting. **`;)`** Any command that get an input works in this case, but I think `pause` better reflects the purpose of that command. – Aacini May 01 '21 at 14:33
0

Without being able to test this, perhaps it would be quicker to run just one tasklist command per loop:

@Echo Off
SetLocal EnableExtensions

:Loop
For /F Tokens^=17^ Delims^=^" %%G In (
    '%SystemRoot%\System32\tasklist.exe /Fi "ImageName Eq cmd.exe" /Fo CSV /NH /V 2^>NUL'
) Do Set /P "=%%G" 0<NUL | %SystemRoot%\System32\findstr.exe /I ^
 "\<%server1%\> \<%server2%\> \<%server3%\> \<%server4%\> \<%server5%\> \<%server6%\>" 1>NUL && GoTo Loop

:Backup

The findstr.exe options may need to be adjusted depending upon the content of those variables.

Compo
  • 36,585
  • 5
  • 27
  • 39
  • Even faster than Einstein's? – Awesome Sounds Apr 25 '21 at 22:24
  • Is that a question or a statement @AwesomeSounds? – Compo Apr 26 '21 at 02:07
  • A question ^^ becouse Einstein's executes like instant.. I'd removed the "timeout 1" becouse I thought: "Who needs timeout for an instant check"... Then I testet it... My i7-8700k still crying bout that :P Added the timeout again... and increased it to 5 – Awesome Sounds Apr 26 '21 at 02:42
  • @AwesomeSounds: first programmer's rule: never build an endless loop without some wait cycles. You've seen why. – Stephan Apr 26 '21 at 06:56