Possa
Possa

Reputation: 2207

Windows batch script launch program and exit console

I have a batch script that I use to launch a program, such as notepad.exe. When I double click on this batch file, notepad starts normally, but the black window of the cmd who launched notepad.exe remains in the background. What do I have to do in order to launch notepad.exe and make the cmd window disappear?

edit: is more complicated than using \I.

The cmd calls cygwin, and cygwin starts notepad. I use

start \I \path\cygwin\bin\bash.exe

and the first window (cmd) disappears, but a second window (\cygwin\bin\bash.exe) is still on the background. In the cygwin script I used notepad.exe & and then exit.

Upvotes: 121

Views: 210035

Answers (7)

Mark Llewellyn
Mark Llewellyn

Reputation: 51

If you want to do everything in a batch file (as asked), I use this technique.

You can read data from within a batch file (and use it by the same batch file) by using the "for /f" command.

For example, here we'll just read the message text at the bottom of the batch file and echo only that in the command window:

@echo off
@for /f "tokens=1,* eol=@ delims= " %%i in (%~0) do @echo %%j
@pause
@rem YOUR MESSAGE HERE:
rem Now is the winter of our discontent
rem Made glorious summer by this sun of York;
rem And all the clouds that lour'd upon our house
rem In the deep bosom of the ocean buried.

The line:

@for /f "tokens=1,* eol=@ delims= " %%i in (%~0) do @echo %%j

is doing the heavy lifting by playing around with the end-of-line character (@) and using the spaces after the bare "rem " lines as the delimeter. I call it "DUYOA.bat", or "Dissappearing Up Your Own...".

Now, we can extend the same principle so that the batch file creates a VBS script, which in turn reads the batch file to create a slave batch file.

The slave batch file is derived from the top of the original batch file wherever "@rem " is the prefix.

Still with me? Don't worry, we're nearly there...

The VBS script is then started by the original batch file, and it runs the slave batch file in the background:

@echo off
rem '   ###########################################
rem '   THIS BATCH FILE READS ITSELF, AND CREATES A  
rem '   VBS SCRIPT TO RUN ITSELF IN THE BACKGROUND
rem '   ###########################################

rem '   NOTE: Prefix your original batch commands with "@rem ":

@rem rem Log the starting of the batch file
@rem echo %date% %time% - %random% Started >> %USERPROFILE%\Desktop\Log.txt
@rem D:\ffmpeg\ffplay -autoexit -nodisp "D:\mp3\Incoming.mp3"
@rem D:\ffmpeg\ffplay -autoexit -nodisp "D:\mp3\Incorrect.mp3"
@rem D:\ffmpeg\ffplay -autoexit -nodisp "D:\mp3\Boing.mp3"
@rem rem Don't play the tada sound
@rem rem D:\ffmpeg\ffplay -autoexit -nodisp "C:\Windows\Media\tada.wav"
@rem rem Log the completion of the batch file
@rem echo %date% %time% - %random% Completed >> %USERPROFILE%\Desktop\Log.txt


rem '   ##########################################################
rem '   THE REST OF THIS SCRIPT STAYS THE SAME, EVEN IF THIS BATCH 
rem '   FILENAME CHANGES. IT AND CAN BE PASTED INTO ANY BATCH FILE
rem '   WHOSE COMMANDS ARE PREFIXED WITH "@rem "
rem '   ##########################################################

rem '   Any line prefixed with "@" is actioned by this master batch file:
rem '   -----------------------------------------------------------------
@set random=%temp%\%~n0%~x0-%random%.vbs
@echo MasterBatchFileName = "%~n0%~x0" > %random%
@for /f "tokens=1,* eol=@ delims= " %%i in (%~0) do @echo %%j >> %random%
@start %random%

rem '   Any line prefixed with "rem " will be written to the VBS script:
rem '   ----------------------------------------------------------------
rem On error resume next
rem Set fso = CreateObject("Scripting.fileSystemObject")
rem SlaveBatchFileName = fso.GetSpecialFolder(2) & "\" & fso.GetTempName & ".bat"
rem Set aFile = fso.CreateTextFile(SlaveBatchFileName, TRUE)
rem Const OPEN_FILE_FOR_READING = 1
rem Set objInputFile = fso.OpenTextFile(MasterBatchFileName, 1)
rem inputData = Split(objInputFile.ReadAll, vbNewline)
rem For each strData In inputData
rem     if left(strData,5)="@rem " then 
rem         aFile.WriteLine(replace(strData,"@rem ",""))
rem     end if 
rem Next
rem aFile.Close
rem objInputFile.Close
rem CreateObject("Wscript.Shell").Run SlaveBatchFileName, 0, True
rem Set aFile = fso.GetFile(SlaveBatchFileName)
rem aFile.Delete
rem Set aFile = fso.GetFile(WScript.ScriptFullName)
rem aFile.Delete

If trying to understand it is giving you a headache, just use the bottom half from:

rem '   THE REST OF THIS SCRIPT STAYS THE SAME...

downwards as a subroutine to paste into your batch files, and just prefix all the original commands with "@rem ".

I shove all the child files in the temp directory, and the VBS script deletes them (and itself) on exit.

You can ditch the logging and all the comments to boil it down, and/or go the other way and add a 3 second pop-up right at the bottom of the file as the very last line:

rem wscript.CreateObject("wscript.Shell").Popup MasterBatchFileName & " completed!",3,MasterBatchFileName,4096+64

Now, I know this doesn't cure the command window flash, but it does run the batch file in the background, and you don't need a separate VBS script lying around as per other answers.

Upvotes: 0

Tomasz Janicki
Tomasz Janicki

Reputation: 99

start "" ExeToExecute

method does not work for me in the case of Xilinx xsdk, because as pointed out by @jeb in the comments below it is actaully a bat file.

so what does not work de-facto is

start "" BatToExecute

I am trying to open xsdk like that and it opens a separate cmd that needs to be closed and xsdk can run on its own

Before launching xsdk I run (source) the Env / Paths (with settings64.bat) so that xsdk.bat command gets recognized (simply as xsdk, withoitu the .bat)

what works with .bat

call BatToExecute

Upvotes: 2

checksum
checksum

Reputation: 6735

start "" "%SystemRoot%\Notepad.exe"

Keep the "" in between start and your application path.


Added explanation:

Normally when we launch a program from a batch file like below, we'll have the black windows at the background like OP said.

%SystemRoot%\Notepad.exe

This was cause by Notepad running in same command prompt (process). The command prompt will close AFTER notepad is closed. To avoid that, we can use the start command to start a separate process like this.

start %SystemRoot%\Notepad.exe

This command is fine as long it doesn't has space in the path. To handle space in the path for just in case, we added the " quotes like this.

start "%SystemRoot%\Notepad.exe"

However running this command would just start another blank command prompt. Why? If you lookup to the start /?, the start command will recognize the argument between the " as the title of the new command prompt it is going to launch. So, to solve that, we have the command like this:

start "" "%SystemRoot%\Notepad.exe"

The first argument of "" is to set the title (which we set as blank), and the second argument of "%SystemRoot%\Notepad.exe" is the target command to run (that support spaces in the path).

If you need to add parameters to the command, just append them quoted, i.e.:

start "" "%SystemRoot%\Notepad.exe" "<filename>" 

Upvotes: 258

brothers28
brothers28

Reputation: 1206

The simplest way ist just to start it with start

start notepad.exe

Here you can find more information about start

Upvotes: 5

MrBogus
MrBogus

Reputation: 49

%ComSpec% /c %systemroot%\notepad.exe

Upvotes: 4

djangofan
djangofan

Reputation: 29669

Hmm... i do it in one of my batch files like this, without using CALL or START :

%SystemRoot%\notepad.exe ..\%URI%
GOTO ENDF

I don't have Cygwin installed though and I am on Windows XP.

Upvotes: 0

Benoit
Benoit

Reputation: 79155

Use start notepad.exe.

More info with start /?.

Upvotes: 11

Related Questions