Wednesday, January 30, 2008

Playing with cmd, start and exit commands and parameters

If you are playing with Windows batch files you are probably using cmd parameters, such as /k to keep cmd box, or /c to close it after command completes, eg:
psexec \\server -e cmd /c "reg import d:\registry_setting.reg"

And similar, you are probably using "exit /b 1" to set errorlevel (returncode) of your script to 1 if it somehow failed.

I havnt used "start" before, but i had a bunch of scheduled tasks and one of those is running every minute, so I figured I would use "start /MIN". This workaround came to mind, because I have no idea how to make sure a tasks is running in session 0 for example, so the repeating task (every minute) can popup with stuff it is doing.. very annoying!

So I added "start /MIN" before my .bat script, but that was not enough. Running the scheduled task would not really start the script. So i added "cmd /C start /MIN somescript.bat", ugly but it worked! Now the scheduled task is minimized on every run.

I noticed that the start command creates its own "cmd /K" process, so my solution results in a process command line like this: "cmd /K somescript.bat". This means that because I am starting the somescript.bat with "start", I now have to add a trailing "exit" in the somescript.bat. Also ugly, but it works.

Now the weird thing I have been puzzled about is a bunch of cmd.exe processes hanging! Using procexp (part of pstools) I can see they are all started from within a Batch control system by running command "start anotherscript.bat". But the anotherscript.bat *does* actually have an exit at the end, so it seems strange that it is hanging. Perhaps it is a hickup in the batch control system!

I can not reproduce a hanging cmd.exe exit command, but I did manage somehow, with a bunch of start, cmd, exit, exit /b 1, etc etc, to create a hanging cmd.exe, where exit command would NOT complete! I dont know how, but in process explorer (procexp), I could see the cmd that was hanging. What could be happening is that exit hangs it self if a child process has disappeared. From the procexp I can not bring window for hanging cmd.exe pid 4696 to front. And then exit command inside cmd.exe pid 4448 is hanging for ever! It did not help to kill 4696 manually, exit of 4448 is still hanging! I had to kill 4448 manually, very annoying!

I suspect it being something weird with start and exit usage, but I am not sure. The exit /? puzzles me, and i am always using exit /B 1 instead of just exit 1. Maybe thats wrong?
exit /?
Quits the CMD.EXE program (command
interpreter) or the current batch
script.

EXIT [/B] [exitCode]

/B specifies to exit the current batch script instead of
CMD.EXE. If executed from outside a batch script, it
will quit CMD.EXE

exitCode
specifies a numeric number. if /B is specified, sets
ERRORLEVEL that number.
If quitting CMD.EXE, sets the process
exit code with that number.

4 comments:

Unknown said...

Hi,

i have seen the following.
a service runs some batch file say '1.cmd'

from '1.cmd' i spawn some processes with
start /b bla.exe
Which works fine, and exit when done..
but when i do a
start '2.cmd' ,it actually performs a
cmd /k 2.cmd' ?!
and the 'exit' which is done from within '2.cmd' doesnt do anything..

Raul Suarez said...

Didyou ever found a solution for the hanging?

We have a similar problem but we have identified that "somescript.bat" starts "anotherscript.bat" which executes a "process".

Esporadically, the "anotherscript" returns control to "somescript" but the "process" is still running.

When this happens, control is not returned to the batch control system (Control-M) until the "process" finishes.

BilgeOne said...

Here's an idea.

Why not create a shortcut to call the batch file. Then set the "Minimized" property of the shortcut.

Then call the shortcut from the Scheduled Task.

Voila! No black box!

Unknown said...

Here's how I do what you are trying to do, if I understand you correctly.

start "Script Name" /min cmd /c yourScript.bat

The /c parameter will allow the cmd to close upon exit or finishing the script. The /min parameter for Start will keep the activity minimized.