2

Im trying to open a 2nd batch file and detect if it normally exited or closed by a user (ctrl+c or x or window termiate etc..) so Im using this following example by Batch run script when closed

@Echo off
set errorlevel=1

    start /w %comspec% /c "mode 70,10&title Folder Confirmation Box&color 1e&echo.&echo. Else the close window&pause>NUL&exit 12345"
    echo %errorlevel%
    pause

Im trying to keep 1st batch waiting (/W) since I will check for errorlevel later on But after closing the 2nd batch file I get an error like ^cterminate batch job (Y/N)?

I tried the suggestion over https://superuser.com/questions/35698/how-to-supress-terminate-batch-job-y-n-confirmation

with the script

rem Bypass "Terminate Batch Job" prompt.
if "%~2"=="-FIXED_CTRL_C" (
   REM Remove the -FIXED_CTRL_C parameter
   SHIFT
) ELSE (
   REM Run the batch with <NUL and -FIXED_CTRL_C
   CALL <NUL %1 -FIXED_CTRL_C %*
   GOTO :EOF
)

That works quite fine So is there a way of starting from same batch file and avoiding the terminating? Or do I have to create a new batch from same batch and call it? (I don't want them to see the file aswell)

Community
  • 1
  • 1
xDeathwing
  • 139
  • 13
  • For reference, the [cause of the problem is described here.](http://stackoverflow.com/questions/25444765/why-does-a-non-interactive-batch-script-think-ive-pressed-control-c) Not a duplicate, because the OP here needs a workaround for his particular scenario rather than just an explanation of why it happens. – Harry Johnston Aug 06 '15 at 23:12

2 Answers2

3
  1. Do not assign values to a volatile environment variable like errorlevel using set command. Doing that causes it becomes unvolatile in current context.
  2. Always use title in START "title" [/D path] [options] "command" [parameters].
  3. start "" /W cmd /c "anycommand&exit /B 12345" always returns 12345 exit code. It's because all the cmd line with & concatenated commands is prepared in parsing time (the same as a command block enclosed in parentheses) and then run entirely, indivisibly. Omit &exit /B 12345 to get proper exit code from anycommand, or replace it with something like start "" /W cmd /c "anycommand&&exit /B 12345||exit /B 54321" to get only success/failure indication.

Next code snippet could help:

@ECHO OFF
SETLOCAL enableextensions

set "_command=2nd_batch_file.bat"
:: for debugging purposes
set "_command=TIMEOUT /T 10 /NOBREAK"

:: raise errorlevel 9009 as a valid file name can't contain a vertical line 
invalid^|command>nul 2>&1

echo before %errorlevel%
start "" /w %comspec% /C "mode 70,10&title Folder Confirmation Box&color 1e&echo(&echo( Else the close window&%_command%" 
echo after  %errorlevel%

Output shows sample %_command% exit codes: 0 or 1 if came to an end properly but -1073741510 if terminated forceably by Ctrl+C or Ctrl+Break or red ×

==>D:\bat\SO\31866091.bat<nul
before 9009
after  0

==>D:\bat\SO\31866091.bat<nul
before 9009
after  1

==>D:\bat\SO\31866091.bat<nul
before 9009
^CTerminate batch job (Y/N)?
after  -1073741510

==>
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • You're still getting the Terminate batch job (Y/N) prompt, though, which is what the OP is trying to eliminate. – Harry Johnston Aug 07 '15 at 02:45
  • @HarryJohnston I don't think that _message_ matters: _Im trying to open a 2nd batch file_ and **detect if it normally exited or closed by a user** – JosefZ Aug 07 '15 at 02:55
  • *But after closing the 2nd batch file I get an error like ^cterminate batch job (Y/N)?* and *So is there a way of starting from same batch file and avoiding the terminating?* – Harry Johnston Aug 07 '15 at 02:57
  • ... and the title of the question is a bit of a clue too. :-) – Harry Johnston Aug 07 '15 at 03:00
  • @HarryJohnston but displaying this message is hard-coded in Windows, I agree BinaryMisfit's answer: [this behavior is by design and controlled by the command interpreter. There is no method of "mapping" or even "intercepting" this unless you de-compile and recompile the interpreter directly](http://superuser.com/a/35701/376602). – JosefZ Aug 07 '15 at 03:03
  • If there's no solution, then the answer is that there's no solution. But I don't think that's true; at the very least, we can prevent the script from waiting for the user to answer yes or no. – Harry Johnston Aug 07 '15 at 03:09
  • It turns out that it is possible; see my answer, which uses a variant on Gringo Suave's answer to the linked question. – Harry Johnston Aug 07 '15 at 03:16
  • +1 for pointing out the issue with `errorlevel` and that it is always wise to include a title with the `start` command. I hadn't spotted either of those. – Harry Johnston Aug 07 '15 at 05:19
2

This works for me:

call :runme start /w "Child Process" %comspec% /c "child.bat & exit 12345" <NUL >NUL 2>NUL 
echo %ERRORLEVEL%
goto :eof

:runme
%*
goto :eof

The idea is to call a subroutine in the current script rather than calling out to an external script. You can still redirect input and output for a subroutine call.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • +1 ? although the `^CTerminate batch job (Y/N)?` redirected somewhere, pressing the `Enter` or `Ctrl+C` return the same exit code of `12345` so where's the OP's request to detect and differentiate them ? (only red `×` returns different exit code). However, let the OP to distinguish or combine our answers... – JosefZ Aug 07 '15 at 04:21
  • @JosefZ: that turns out to be an artifact of the `pause` command. If we run a child batch script as per the OPs scenario it doesn't happen. I've updated my answer accordingly. – Harry Johnston Aug 07 '15 at 05:17
  • Is the intent here to detect whether child.bat exited normally, for which `exit 12345` sets the exit code to a known value? An abnormal exit could be from closing the child console window, which sets the exit code to `STATUS_CONTROL_C_EXIT` (-1073741510). Terminating child.bat via Ctrl+C or Ctrl+Break in the child console sets the exit code to 255 or 1. Redirecting stdin to NUL in the parent short circuits the "Terminate batch job (Y/N)?" prompt and effectively answers no. Redirecting stdout and stderr to NUL hides the latter prompt. – Eryk Sun Sep 22 '17 at 01:20
  • @eryksun, I don't really remember. I think the `exit 12345` may have been included in my answer simply because it appears in the question. I suppose it is necessary if you don't know what exit code `child.bat` returns, but still want to determine whether `child.bat` exited naturally or was aborted. – Harry Johnston Sep 22 '17 at 02:34