11

There are many references on Internet claiming that one of differences between a GUI and a console application is that running the GUI application from a batch file does not block its execution, while running the console application does block it.

Few of many references, these are particularly from SO/SE:

Moreover, I myself remember this is/was true.

Yet it does not seem to work this way.

I've tested this on a simple batch file like:

echo Pre
notepad
echo Post

The Post is not printed until I close notepad. Why, when a notepad is clearly a GUI application?

I've tested this on Windows 8, 7, and XP just to rule out a possibility that the behavior has changed in recent versions of Windows. I've tried to disable command extensions as one of possible culprits too.

5
  • Good one. I first though it was easy to answer, but it is not. FYI, I use vim on Windows (gvim.exe) and it does not block like others do. Could be a trick long those lines ?
    – ixe013
    Commented Oct 15, 2013 at 13:52
  • 1
    Very interesting. It blocks from within a batch script, but does not block from the command prompt. Try echo pre&notepad&echo post in both contexts. I never noticed this difference until you raised the question.
    – dbenham
    Commented Oct 15, 2013 at 14:51
  • I think whether it returns control to the caller or not depends on the architecture of the GUI application in question. Is it Win32, console, CLR, STA, multi-threaded, etc.
    – orad
    Commented Nov 3, 2013 at 3:07
  • Any GUI application is Win32, AFAIK. GUI application is not a console application. And I do not believe that Windows consider an application framework (CLR/STA) when treating a process (that would be very bad). So I would consider only multi-threading plausible. Commented Nov 4, 2013 at 9:10
  • @DavidCandy But all the references, I've found deal with waiting for GUI application from a batch file, so I do not think this explains it. Commented Nov 11, 2013 at 7:56

4 Answers 4

10
+25

It has to do with how the application that you launch runs and terminates. Some programs launch another process and then terminate, others continue to run. Calc.exe and Notepad.exe simply run until you close them. Write.exe and any program that launches as a result of a file association (e.g., bitmap, wave file, control panel applet, etc.), actually launch another program and then the process that launched them terminates returning control back to the batch file so it can execute the next line.

Here are some examples:

@echo off

echo Starting Calc.exe
calc.exe
echo Calc was closed by the user

echo Starting Notepad.exe
Notepad.exe
echo Notepad was closed by the user

echo Starting WordPad.exe
write.exe
echo Write launched WordPad and then terminated allowing the batchfile to continue

echo Starting Services.msc
services.msc
echo Windows launched MMC, opened services.msc, then returned control to the batchfile

echo Launching WMP via Chord.wav
c:\windows\media\chord.wav
echo Windows launched WMP, opened Chord.wav, then returned control to the batchfile

The CMD process knows Calc and Notepad are still running because it spawned them itself. The CMD process does not know that the others are still running because the intermediate process terminated.

To observe this, open Process Explorer and view the processes displayed in the hierarchical tree. Calc.exe and Notepad.exe both remain as child processes of the CMD process that ran the batchfile. Write.exe and MMC.exe (services.msc) both become top-level processes, no longer children to the CMD process. WMPlayer.exe remains a child process to svchost.exe, which is how Windows launched it. The CMD process doesn't know they are still running because it didn't launch them, some other Windows process did. So execution continues...

One more example of this is how MSPaint.exe functions. If you run it by using the Windows built-in file association for BMPs, then Windows launches MSPaint.exe and control is immediately returned to the batchfile. However, if you pass the BMP to MSPaint.exe, then the batchfile waits for you to close MSPaint before continuing. (I'm on a dev machine with no BMPs, so create a simple one called C:\MyBitmap.bmp.)

@echo off
C:\MyBitmap.bmp
calc.exe
mspaint.exe C:\MyBitmap.bmp
notepad.exe

Calc.exe will open immediately, Notepad.exe will not open until you close the second instance of MSPaint.exe.

I know you didn't ask about launching Windows processes via their file association, but it just demonstrates how the owning process can change. If the CMD process owns the launched process, it should wait until it terminates to continue execution. If the spawned process hands control off to another process, then the CMD process doesn't know about the grandchild process and it continues on with its execution.

5
  • 1
    Thanks for your response. Though it does not answer my question. See the references in my question, they definitely does not deal with process that use the technique you describe (that I'm aware of). For example the (second)[stackoverflow.com/questions/8177695/…. It deals with notepad as if it does not block a batch file. Obviously notepad does not use the technique. Commented Nov 11, 2013 at 8:00
  • You wanted to know why GUI apps block the batch file from continuing to execute until the GUI app terminates. That is precisely what I described. Regardless of what is said in the links you referenced, the CMD processor does not execute the next line in a batch file until a program it launches has terminated. Sometimes a program will create another process (grandchild to the CMD process) and then terminate. The CMD interpreter sees the process it launched terminated, and it continues execution. Otherwise it waits. It doesn't matter if it is a GUI app or a console app. The result is the same.
    – James L.
    Commented Nov 13, 2013 at 18:21
  • 2
    Using start to launch a program (without the /wait option) changes the behavior of the CMD processor. Instead of waiting for the process to terminate before it continues, it simply continues. If you don't use start, it will always wait until the program it launched terminates. It will never wait for a grandchild process to terminate. It only watches the immediate child process it created itself.
    – James L.
    Commented Nov 13, 2013 at 18:24
  • If you consider only a subject of my question, then yes, your answer is correct. If you read it completely, than not. I cannot put everything into a short subject. I was asking why PEOPLE BELIEVE the batch files does not block. Maybe I put it wrong, my fault. Anyway, it does not look like I get proper answer. I just cannot believe all those discussions here on SO and elsewhere are completely wrong. The bounty expires soon, so it looks like it goes to you :) Commented Nov 14, 2013 at 8:13
  • @MartinPrikryl: There was never anything in your question about people's beliefs. And if there were, your question would qualify as off-topic because it would have been opinion-based. The substance of your question has indeed been answered here, I just don't see the point of drawing more attention to your otherwise perfectly valid question.
    – Andriy M
    Commented May 21, 2015 at 6:52
4

Because it waits for return code.You can use start command to create a separate subprocess:

@echo pre
@start "notepad" notepad
@echo post
5
  • Thanks for your answer. What does it mean "it waits for return code"? (as opposite to "it waits for process termination"?). I know I can use start, I just believe it should work without it. Commented Oct 15, 2013 at 13:10
  • it should be the same.After each called .exe the command prompt expect a return code to check if command was successfully executed.E.g. color.exe 55 & echo %errorlevel% . color 55 will fail and will set the errorlevel 1.
    – npocmaka
    Commented Oct 15, 2013 at 13:30
  • 2
    Ok, but you miss the point of my question. What you say should not be true, check the references in my question. They all deal with how to make batch wait for process to finish (as if it actually did not). Commented Oct 15, 2013 at 13:41
  • I should delete my answer.Anyway - there's a way to check if applications that comes with windows will block the console - the non-blocking(not mandatory GUI) will have This program cannot be run in DOS mode. string written somewhere in them (you can use type command, text editor or strings.exe ->technet.microsoft.com/en-us/sysinternals/… will be not true for external applications , but it will be for applications built with visual studio.(notepad does not have it , but it's presented in write.exe).Probably this is the reason - bit.ly/167vF8R
    – npocmaka
    Commented Oct 15, 2013 at 14:28
  • @DavidCandy : Not at all. DOS stubs 'replace the need' of having a DOS app. PE was designed to work with both a version of windows and it's DOS version in a single file. See here Commented Nov 6, 2013 at 14:39
1

I've used Windows since NT 3.1, and I too would have said "cmd.exe does not wait for GUI programs to terminate" when you simply type the name of the program (as opposed to using the START command). Though memory grows dim, I believe it originally worked this way. But today, my statement is true interactively, false for "batch" files. Having been thus reminded, I vaguely think it was intentionally changed as some point, since the naïve batch-writer expects sequential execution, but I can't be sure and I don't know when.

0

I think the answer lies in this question Difference between Windows and Console application.

I quote from two answers.

Konrad Rudolph answered:

The sole difference is that a console application always spawns a console if it isn't started from one (or the console is actively suppressed on startup). A windows application, on the other hand, does not spawn a console. It can still attach to an existant console or create a new one using AllocConsole.

This makes Windows applications better suited for GUI applications or background applications because you usually don't want to have a terminal window created for those.

oefe answered:

Console and Windows applications behave differently when called interactively from the command prompt:

When you start a console application, the command prompt doesn't return until the console application exits. When you start a windows application, the command returns immediately.

This is not true for batch files; they will always wait until the application exits.

The difference in this bahviour between cmd and batch made you think that it worked before.

1
  • Thanks for your answer. I have always been aware of this difference. While it may have confused me, it does not explain why other questions asking for the same exist. Commented Jan 24, 2016 at 15:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.