2

I'm executing an script (.cmd) inside a shell (c:\windows\system32\cmd.exe). What I want is that when a command returns an errorcode the .cmd file ends its execution and then cmd.exe also ends its executing returning the errorcode to the one that called it.

I'm using something like this:

C:\...\gacutil.exe /i C:\...\x.dll
if not errorlevel 0 (
    echo Error registering C:\...\x.dll
    exit %errorlevel%
)

But this does not work. I tried with exit /b but looks the same to me. Any idea?

Ignacio Soler Garcia
  • 21,122
  • 31
  • 128
  • 207
  • Do you mean exiting an interactive session of the shell using the batch script you've run in that same session? – Andriy M Feb 01 '11 at 17:57
  • Rigth, I'm running that session from a remote location and I want to end it from the batch to make the session return the errorlevel taken from the command that had the error. – Ignacio Soler Garcia Feb 01 '11 at 18:37
  • I see. That last part about returning the errorlevel somewhat complicates things. I was thinking about some way to kill the session, for which it would be necessary first to find out its PID, though. Anyway, it seems you need something different so you could return the result as well... – Andriy M Feb 01 '11 at 20:45
  • And you cannot possibly run your script non-interactively, can you? – Andriy M Feb 01 '11 at 20:48
  • Yes, the whole thing is unattended so I can run the script without user interaction. Why? – Ignacio Soler Garcia Feb 02 '11 at 07:37
  • I thought your batch script was fired manually in the cmd session opened prior to running the script, so I tried to figure out how to close that session. I now see what and where the problem was. Sorry for being so dumb. – Andriy M Feb 02 '11 at 23:02
  • Andriy: no problem at all dude, on the contrary thanks for trying to help! – Ignacio Soler Garcia Feb 03 '11 at 07:27

3 Answers3

5

This comes up every now and then, IMHO exit and exit /b are broken since they only set the errorlevel used by batch files, but they do not set the exit code of the cmd.exe process.

If a batch script is doing the errorlevel checking, call is enough:

REM DoSomeAction.cmd
@echo off
call someprogram.exe
if errorlevel 1 exit /b 

REM MainScript.cmd
@echo off
...
call DoSomeAction.cmd
if errorlevel 1 (
  ...
)

But if you want to use && or || syntax (myscript.cmd&&someotherapp.exe) or your script is started from a program and not another batch file, you actually want to set the process exit code (Retrieved with GetExitCodeProcess in the parent process)

@echo off
call thiswillfail.exe 2>nul
if errorlevel 1 goto diewitherror
...
REM This code HAS to be at the end of the batch file
REM The next command just makes sure errorlevel is 0
verify>nul
:diewitherror
@%COMSPEC% /C exit %errorlevel% >nul

Using a "normal" exit /b and then calling it with call myscript.cmd&&someotherapp.exe does work, but you can't assume that every program that executes a batch file will create the process as cmd.exe /c call yourscript.cmd

Community
  • 1
  • 1
Anders
  • 97,548
  • 12
  • 110
  • 164
1

You can (ab)use GOTO's bug when it is with non existent label and negative conditional execution.In this case the cmd.exe from batch script mode to command prompt mode and can be exited:

C:\...\gacutil.exe /i C:\...\x.dll
if not errorlevel 0 (
    echo Error registering C:\...\x.dll
    goto :no_such_label >nul 2>&1 || exit %errorlevel%
)
Community
  • 1
  • 1
npocmaka
  • 55,367
  • 18
  • 148
  • 187
1

It's all about the shell that's actually running the script. When a script executes it is run in a subshell, so calling exit just exits that subshell. However, I think that if you execute the script by using the call statement it will execute within the context of that shell and not execute a subshell.

So, to execute the script use

call <script.cmd>

and not just

<script.cmd>
disrvptor
  • 1,592
  • 12
  • 23