1

here my question is I want to close a windows bat dos window directly, and when the close action is invoked, some actions or another bat should be invoked, how can i implement this?

what I am doing is like this : I start a bat, and the bat start two processes, when the dos bat closed,the two process should also be closed. The users often close the dos window directly,don't use the stop.bat I provided, So I am thinking about is it possible to catch the user's close action and do something!!

thank you !!!!

Winston
  • 1,202
  • 1
  • 13
  • 19
  • maybe this solution works:{http://stackoverflow.com/questions/9277630/windows-shutdown-hook-on-java-application-run-from-a-bat-script} but it uses java native, which get it complicated,Is there any simple solution? – Winston Aug 09 '13 at 06:12
  • 1
    I think it is impossible to do this using pure Batch Scripts, however it *may* be possible with aid of another language... – BDM Aug 09 '13 at 06:19

4 Answers4

1

Well, I have solved this problem. the main idea is from [Windows shutdown hook on java application run from a bat script], but the answer has a bug, that is if I close the Bat or Cmd forcibly,The action may not be invoked, the reason here is The JVM shutdown before the java code action invoked. so I put the action in native method.

Community
  • 1
  • 1
Winston
  • 1,202
  • 1
  • 13
  • 19
0

I recently did something like this. Basically the way I managed to get it work was that I had another batch file (we'll call it bat2) launch when we started the main batch file (we'll call this one bat1).

:start
tasklist /v | Find "BAT1'S WINDOW NAME GOES HERE"
if "%ERRORLEVEL%"=="1" COMMAND TO EXECUTE WHEN THE WINDOW IS CLOSED
if "%ERRORLEVEL%"=="1" exit
timeout /t 1 /NOBREAK >nul
goto :start

That's the script I used for bat2. It's probably not as good as it could be but I'm very new to this stuff so it's the best I could come up with.

Hope this helps you!

0

Just a note on the previous entry by AstralBacon. You can simplify it like so:

:start
tasklist /v | Find "BAT1'S WINDOW NAME GOES HERE"
if "%ERRORLEVEL%"=="1" (
  COMMAND TO EXECUTE WHEN THE WINDOW IS CLOSED
  exit
)
timeout /t 1 /NOBREAK >nul
goto :start
Giraugh
  • 116
  • 6
0

Using a second Batch is the way to go as the other answers have suggested.

But searching through your entire verbose tasklist with "tasklist /v" is a very slow and ineffective process. Takes multiple seconds on my machine. You can manipuate the tasklist command output to only show your batch (which is way more effective) and use that output directly like this without needing a pipe:

:START
for /f "tokens=1 delims=," %%G in ('tasklist /FI "WINDOWTITLE EQ TITLE_OF_ORIGINAL_BATCH" /FO CSV /NH') do (
   if not %%G=="cmd.exe" (
      REM EXECUTE COMMANDS WHEN THE WINDOW IS CLOSED
      exit
   )
)
ping 127.0.0.1>nul
goto START

Explanation: First we fetch a single line of csv-style tasklist output which would either look like this if it finds your batch:

"cmd.exe","8172","Console","1","4.228 K"

or like this if there's no such window title in the tasklist:

"INFORMATION: blablabla..."

We throw this into that FOR /F loop that runs only once and only picks the first token:

"cmd.exe" or "INFORMATION: blablabla...".

Now "cmd.exe"/"INFO..." is in variable %G that can be used in an IF statement to get the definitive answer wether the other task is alive or dead.

Bonus fact: You can use a single .bat file to launch both scripts simultanously like this:

@echo off
if "%1" == "" start "" "%~f0" FLAG && goto actual_script

title EXIT_CHECK
:START
for /f "tokens=1 delims=," %%G in ('tasklist /FI "WINDOWTITLE EQ ORIGINAL_BATCH" /FO CSV /NH') do (
   if not %%G=="cmd.exe" (
      REM COMMANDS TO EXECUTE HERE WHEN THE MAIN WINDOW IS CLOSED
      exit
   )
)
ping -n 2 127.0.0.1>nul
goto START

:actual_script
title ORIGINAL_BATCH
:loop
REM SCRIPT GOES HERE
ping -n 2 127.0.0.1>nul
goto loop
drdim
  • 1