65

My problem is that in Windows, there are command line windows that close immediately after execution. To solve this, I want the default behavior to be that the window is kept open. Normally, this behavior can be avoided with three methods that come to my mind:

  1. Putting a pause line after batch programs to prompt the user to press a key before exiting
  2. Running these batch files or other command line manipulating tools (even service starting, restarting, etc. with net start xy or anything similar) within cmd.exe(Start - Run - cmd.exe)
  3. Running these programs with cmd /k like this: cmd /k myprogram.bat

But there are some other cases in which the user:

  1. Runs the program the first time and doesn't know that the given program will run in Command Prompt (Windows Command Processor) e.g. when running a shortcut from Start menu (or from somewhere else), OR
  2. Finds it a little bit uncomfortable to run cmd.exe all the time and doesn't have the time/opportunity to rewrite the code of these commands everywhere to put a pause after them or avoid exiting explicitly.

I've read an article about changing default behavior of cmd.exe when opening it explicitly, with creating an AutoRun entry and manipulating its content in these locations:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor\AutoRun

(The AutoRun items are _String values_...)

I put cmd /d /k as a value of it to give it a try, but this didn't change the behaviour of the stuffs mentioned above at all... It just changed the behaviour of the command line window when opening it explicitly (Start-Run-cmd.exe).

So how does it work? Can you give me any ideas to solve this problem?

10
  • 12
    Your question with all the explanations made my head want to explode. Can you say something like: I want to run a batch file with this "example" command, and I want the command box to stay open when finished. Is that what you are asking? Please put in a close sample of the code.
    – KCotreau
    Jul 4, 2011 at 15:40
  • 1
    +1 Agreed. A little to verbose, please reconsider your question and, if possible, use an example and compose a more succinct question. Jul 4, 2011 at 15:47
  • 2
    This is normal behaviour, and while your question certainly is valid, you should be questioning why you need to keep the command prompt open after (most utilities are created with this caveat in mind). Jul 4, 2011 at 16:16
  • 1
    In my opinion, this is not a real question. As you just instruct the user to use a batch file instead. If that's not the intent of the question, please clarify your question by removing any confusing information and explain what your real goal is. It's hard to come up with the right answer if it's unclear... Jul 4, 2011 at 17:21
  • 1
    @Randolf Richardson, that's because those tools aren't supposed to be seen by an end-user ever (after all, that's why we use GUIs now). If you did need such information, most IT groups will send out batch files to gather them the appropriate system information and display it. I can see no possible way that if a solution to this question is found, it will cause less problems then it solves - so many things are sent to stdout on a constant basis which were never meant to be visible for a good reason. Jul 4, 2011 at 18:55

12 Answers 12

29

I have a solution which can only apply on .cmd and .bat files:

Open regedit and go to each one of:

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
[HKEY_CLASSES_ROOT\cmdfile\shell\open\command] 

Now change the "Default key value" to cmd.exe /k "%1" %*. Now, every batch script window will stay open after its execution.

Note that this is like using cmd.exe /c cmd.exe /k program.bat, meaning that another CMD instance will be launched into the parent one. I couldn't find how to overwrite the first /c argument.

You can also do so with [exefile], but now it'll show an empty console box if the executable has a GUI.

3
  • 5
    +1 for having the only solution here which actually answers the question given. Unfortunately, I think this may be a memory leak waiting to happen. What happens when a service launches a new batch file without specifying CMD.EXE in the CMD line? Won't this code be used in that case? Isn't this going to create a new window on a non interactive desktop and leave it open until you restart?
    – krowe2
    Nov 20, 2014 at 20:10
  • @APerson Your edit broke the command by not including the *. Please be more careful when editing!
    – not2qubit
    May 28, 2017 at 11:25
  • @not2qubit Sorry, didn't notice that I deleted three asterisks instead of two. Will do.
    – APerson
    May 30, 2017 at 3:04
17

Quote Microsoft:

A console is closed when the last process attached to it terminates or calls FreeConsole.

In other words, Win32 console window will always be closed when the last program running inside it exits, and you cannot change this.


(For 16-bit MS-DOS programs, Windows offers an option "Close on exit" in the properties dialog, but this is not an exception to the behavior above: it's the NTVDM process that holds the window open. Also, this option is again per-program.)

2
  • 13
    +1 for understanding how and why console windows close (as opposed to most who just say "OMG WHY CAN'T IT STAY OPEN!!!!!!!!!!!1111one"). It's behaving as designed, and it should stay that way IMHO. This is the primary reason why we have standard streams and batch files in the first place. Jul 4, 2011 at 19:29
  • 35
    @Breakthrough The question is How can I do X, not In your opinion, should I do X. This answer is unhelpful, it implies X is impossible, when partial solutions have already been presented elsewhere. (-1)
    – Superbest
    Jun 9, 2014 at 18:07
9

Just open a command prompt at the location of your batch file, and manually key in the name of your batch file to run it within that window.

1.Navigate to the folder where your executable resides
2.Shift-Right click and select "Command Window from here"
3.type in the name of the executable and hit enter
4.The process should run, but the window should stay open

3
  • 1
    I didn't know about Shift+Right click. Also, however, you can drag-drop the exe into a cmd window, which automatically puts in the path for you.
    – Superbest
    Jun 9, 2014 at 18:08
  • 1
    This usually works for me, but it's apparently not a sure thing because I'm here searching for a solution precisely because it's not working in my current situation.
    – RenniePet
    Oct 13, 2016 at 18:10
  • this is the most easiest solution and must be marked as the correct answer Mar 8, 2017 at 1:40
5

cmd.exe /k will give you trouble with some batch. If the batch exit 1 (without /B) your console will be closed. A trick is to use:

cmd.exe /k cmd /c ...

To use this by default for all batch files, set HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default) and HKEY_CLASSES_ROOT\batfile\shell\open\command\(default) to "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.

2
  • 1
    I thought that "%*" passes the full parameter list, so wouldn't this pass the first parameter twice, once as "%1" and again as the first parameter of "%*" ? Mar 21, 2013 at 18:49
  • 1
    @KevinFegan I haven't checked the reason but %1 should keep the quotes which means it would be possibly double quoted in some cases. There is also a difference between %1 %2 %3 .. and %* which I don't remember right now but the %1 %2 %3 works in some cases where %* fails.
    – Wernight
    Apr 26, 2013 at 8:28
4

I just hit on a dumb solution after reading grawity's answer.

My use case was setting up a console environment at work where all the more reasonable solutions are blocked. All I need is to set PATH and configure some doskey aliases and be dumped to the shell.

My solution (just tested on Win7) as add cmd as the last line in the batch file. This runs a nested command prompt that inherits the environment of its parent. That child shell holds the batch process open until you EXIT, at which point the batch has no child processes and also exits.

3

Rather than using PAUSE (I prefer CHOICE or TIMEOUT to using PAUSE when necessary), you can use the solution here: 886848/how-to-make-windows-batch-file-pause-when-double-clicked.

This way, if you click on a batch file or link (shortcut) from within Windows Explorer, you can have the batch file program pause before it exits so you can view the program output and any error messages.

Using CHOICE, you can program the ability for the user to select a variety of actions to take, and using TIMEOUT can let the window close after a time delay (unattended). If you run the batch file from within a command prompt window, these pauses can be annoying.

The linked solution will let you decide if you want to skip the pauses if the batch file was run from a command prompt window.

You can read more at the provided link, but the basics of it is that it uses the environment variable:

%cmdcmdline%

to determine if the batch file was run from a command window or not.

So, you use it like this:

At the point where the batch file will exit, you add some code like this:

echo %cmdcmdline:"=-% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% NEQ 0 goto :EOF
pause
goto :EOF

rem if %errorlevel% EQU 0 batch-file: %~dpf0 was executed from Windows Explorer, ...
rem if %errorlevel% NEQ 0 batch-file: %~dpf0 was executed from within a Command Prompt
2

Suppose you have two batch files you want to launch in their own instance and keep open if their executable exits. Lets call those two batches A.bat and B.bat.

Now for simplicity you could have a batch file to launch them both, let's call that launch_both.bat with contents:

start cmd /k "A.bat & cmd /c"
start cmd /k "B.bat & cmd /c"

It might not work as expected if you call exit in one of the two batch files. That will need to be tested.

2

In response to downgraded PSIXO - "This answer was already covered in the question. – Ro Yo Mi Jan 20 '16 at 5:06" -- NO, it was NOT. The previous answers were: "pause", which did NOT work. PSIXO's answer was: "& pause", which DOES work. Please parse more carefully before downgrading. I ran this from an IDLE prompt, and it worked:

    >>> os.system('dir ^ & pause')
    0
    >>> 

On the other hand:

    >>> os.system('dir ^ pause')
    1
    >>>

Did NOT work (the cmd prompt blipped over, and in fact returned an error (1)). Thanks to PSIXO for the answer that I needed. Henry.

2

This works for version 5.00 of the Windows Registry Editor.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

Save the above cmds in a file called something like cmdbatfile-open.reg and execute it!

1
1

The best way I have found to get around this is to call your batch files from another batch file using start.

so if you normally run a file called go.bat, then you would create a second batch file named something like go2.bat

the contents of go2.bat would just be

start go.bat

the first window closes immediately, but the one running your go.bat remains open

1
  • This works, I just put the name of the command prompt executable in one bat file (1.bat) which is called using start command from a second bat file "start 1.bat". Command window stays open. Sep 19, 2017 at 9:16
1

For users using Windows 10, note that none of the answers above currently work for Windows 10.

For Windows 10, if you have access to the script, you need to add the following code at the end:

read

That code will wait for an input before closing.

1
  • Remember the question was asked before Windows 10 (5 years ago), please edit your answer with more information
    – yass
    Mar 30, 2017 at 8:41
1

The OP's question is much more involved than what I needed, and so this answer is for others who come here looking for a simple way to launch a command line program and keep the window open after the command line program exits.

In my case, I wanted to run NodeJS and keep the console window open after NodeJS stopped. Here was my solution:

File: RunNodeJS.bat

@echo off
cd /d c:\
cmd.exe /k cmd /c node

I then created a shortcut to that file on my desktop and double click the shortcut to launch a cmd.exe console that runs the node command and remains open after it (the node command) exits.

I used cmd.exe /k cmd /c node because of another answer given here.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .