102

I have a "setup" script which I run in the morning which starts all the programs that I need. Now some of those need additional setup of the environment, so I need to wrap them in small BAT scripts.

How do I run such a script on Windows XP in the background?

CALL env-script.bat runs it synchronously, i.e. the setup script can continue only after the command in the env-script has terminated.

START/B env-script.bat runs another instance of CMD.exe in the same command prompt, leaving it in a really messy state (I see the output of the nested CMD.exe, keyboard is dead for a while, script is not executed).

START/B CMD env-script.bat yields the same result. None of the flags in CMD seem to match my bill.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • `which I run in the morning which starts all the programs that I need` we are the same! haha ~ everytime I start the PC, I need to run many programs before working. – Siwei Sep 28 '22 at 23:10

7 Answers7

160

Two years old, but for completeness...

Standard, inline approach: (i.e. behaviour you'd get when using & in Linux)

START /B CMD /C CALL "foo.bat" [args [...]]

Notes: 1. CALL is paired with the .bat file because that where it usually goes.. (i.e. This is just an extension to the CMD /C CALL "foo.bat" form to make it asynchronous. Usually, it's required to correctly get exit codes, but that's a non-issue here.); 2. Double quotes around the .bat file is only needed if the name contains spaces. (The name could be a path in which case there's more likelihood of that.).

If you don't want the output:

START /B CMD /C CALL "foo.bat" [args [...]] >NUL 2>&1

If you want the bat to be run on an independent console: (i.e. another window)

START CMD /C CALL "foo.bat" [args [...]]

If you want the other window to hang around afterwards:

START CMD /K CALL "foo.bat" [args [...]]

Note: This is actually poor form unless you have users that specifically want to use the opened window as a normal console. If you just want the window to stick around in order to see the output, it's better off putting a PAUSE at the end of the bat file. Or even yet, add ^& PAUSE after the command line:

START CMD /C CALL "foo.bat" [args [...]] ^& PAUSE
antak
  • 19,481
  • 9
  • 72
  • 80
  • 10
    `&` is an "and then" (terminology?) operator. (e.g. `cmd1 & cmd2` means do "cmd1" and then "cmd2". Unlike the `&&` operator, execution of "cmd2" doesn't depend on the successful exit of "cmd1".) The `^` escapes the `&` so that it goes into CMD's arguments instead of being consumed and run by the same console that ran START. – antak Dec 08 '11 at 01:56
  • This is very helpful, thanks. I was just about to port some scripts to Linux, because other guides to `start` and `cmd` didn't give the full functionality I sought. Your answer nails it. – Iterator Dec 17 '11 at 01:34
  • 4
    If you don't want the output then the redirection must be escaped so that it gets passed to CMD. Also CALL is not needed: `START /B "" CMD /C "foo.bat" [args [...]] ^>nul 2^>^&1` – dbenham Jul 30 '12 at 01:21
  • 1
    @dbenham: Although what you're saying makes sense, `START /B "" CMD /C PING 127.0.0.1 >NUL` seems to work regardless and nothing is output. (Probably because `CMD` inherits `START`'s I/O handles.) I guess the difference is if you want to keep `START`'s (error) output intact, which is probably a good idea. `CALL` is just there because I felt it's a good practice to keep. (i.e. Not using `CALL` for *synchronous* bat calls will result in unpredictable exit codes, so I consistently pair bat calls with `CALL` even when it doesn't strictly apply, such as in this case.) – antak Jul 30 '12 at 08:01
  • Worked with me like a charm. FOR %%y IN (* --dev-- *) DO START /B CMD /C CALL "%%y" – Asif Ashraf Nov 14 '21 at 06:17
72

Actually, the following works fine for me and creates new windows:

test.cmd:

@echo off
start test2.cmd
start test3.cmd
echo Foo
pause

test2.cmd

@echo off
echo Test 2
pause
exit

test3.cmd

@echo off
echo Test 3
pause
exit

Combine that with parameters to start, such as /min, as Moshe pointed out if you don't want the new windows to spawn in front of you.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • 1
    Okay, this works but isn't 100% perfect: After I press "RETURN" in "Test 2", that window doesn't close. Any ideas? – Aaron Digulla Mar 16 '09 at 12:26
  • You can add "exit" to the spawned batches to close them afterwards again. Sorry, didn't test that far :) – Joey Mar 16 '09 at 12:56
  • in fact the start script1.bat \n start script2.bat \n start scriptN.bat was sufficient for me – andrej Sep 16 '20 at 13:31
9

Since START is the only way to execute something in the background from a CMD script, I would recommend you keep using it. Instead of the /B modifier, try /MIN so the newly created window won't bother you. Also, you can set the priority to something lower with /LOW or /BELOWNORMAL, which should improve your system responsiveness.

Moshe
  • 2,638
  • 2
  • 28
  • 32
  • -1 The problem is that START doesn't create a new window when you start a BAT file; instead it reuses the current window and mixes the I/O two CMD processes. – Aaron Digulla Mar 16 '09 at 09:02
  • 5
    It is not creating a new window because you're using the /B flag. Remove it. – Moshe Mar 16 '09 at 14:08
6

Other than foreground/background term. Another way to hide running window is via vbscript, if is is still available in your system.

DIM objShell
set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("yourcommand.exe", 0, TRUE)

name it as sth.vbs and call it from bat, put in sheduled task, etc. PersonallyI'll disable vbs with no haste at any Windows system I manage :)

MeaCulpa
  • 881
  • 1
  • 6
  • 14
  • 1
    For my particular use case, this was actually the only solution I could get to work... – Ben Jul 21 '16 at 14:44
0

Actually is quite easy with this option at the end:

c:\start BATCH.bat -WindowStyle Hidden

Sahil Mahajan Mj
  • 11,033
  • 8
  • 53
  • 100
0

Create a new C# Windows application and call this method from main:

public static void RunBatchFile(string filename)
{
    Process process = new Process();

    process.StartInfo.FileName = filename;

    // suppress output (command window still gets created)
    process.StartInfo.Arguments = "> NULL";

    process.Start();
    process.WaitForExit();
}
LegendLength
  • 473
  • 3
  • 11
  • 2
    Uhm ... I was hoping that something as simple as that wouldn't need installing Visual Studio ... – Aaron Digulla Mar 16 '09 at 12:28
  • 1
    Until PowerShell is available 100% - C# is really overkill. – jim Mar 16 '09 at 12:42
  • 2
    Aaron: The C# compiler is included in the .NET Framework 2, so you can just edit some code in a text editor and compile it. Still, since this is perfectly possible in a batch file I'd also say C# is overkill. – Joey Mar 16 '09 at 13:16
0

This works on my Windows XP Home installation, the Unix way:

call notepad.exe & 
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MiiToo
  • 49
  • 1
  • 1