为什么GUI应用程序阻止批处理文件?

时间:2013-10-15 12:19:25

标签: batch-file

互联网上有许多引用声称GUI和控制台应用程序之间的区别之一是从批处理文件运行GUI应用程序不会阻止其执行,而运行控制台应用程序会阻止它。

很多参考资料中,特别是来自SO / SE:

此外,我自己也记得这是/是真的。

但它似乎没有这种方式。

我在一个简单的批处理文件中对此进行了测试,例如:

echo Pre
notepad
echo Post

在关闭记事本之前,Post不打印。为什么,当记事本显然是一个GUI应用程序?

我在Windows 8,7和XP上对此进行了测试,以排除在最近版本的Windows中行为发生变化的可能性。我试图将命令扩展禁用为可能的罪魁祸首之一。

4 个答案:

答案 0 :(得分:9)

它与您启动的应用程序如何运行和终止有关。一些程序启动另一个进程然后终止,其他程序继续运行。 Calc.exe和Notepad.exe只是运行,直到您关闭它们。 Write.exe和由于文件关联而启动的任何程序(例如,位图,波形文件,控制面板小程序等),实际启动另一个程序,然后启动它们的进程终止将控制权返回到批处理文件所以它可以执行下一行。

以下是一些例子:

@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

CMD进程知道Calc和Notepad仍然在运行,因为它自己产生了它们。 CMD进程知道其他进程仍在运行,因为中间进程已终止。

要观察此情况,请打开Process Explorer并查看分层树中显示的进程。 Calc.exe和Notepad.exe都作为运行批处理文件的CMD进程的子进程保留。 Write.exe和MMC.exe(services.msc)都成为顶级进程,不再是CMD进程的子进程。 WMPlayer.exe仍然是svchost.exe的子进程,这是Windows启动它的方式。 CMD进程不知道它们仍在运行,因为没有启动它们,其他一些Windows进程也没有。所以执行继续......

另一个例子是MSPaint.exe的功能。如果使用Windows内置文件关联为BMP运行它,则Windows将启动MSPaint.exe,并立即将控制权返回给批处理文件。但是,如果将BMP传递给MSPaint.exe,则批处理文件会在继续之前等待您关闭MSPaint。 (我在没有BMP的开发机器上,所以创建一个名为C:\ MyBitmap.bmp的简单机器。)

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

Calc.exe将立即打开,在关闭MSPaint.exe的第二个实例之前,Notepad.exe将无法打开。

我知道您没有询问是否通过文件关联启动Windows进程,但它只是演示了拥有进程如何更改。如果CMD进程拥有已启动的进程,则应等待它终止以继续执行。如果生成的进程将控制权转移到另一个进程,则CMD进程不知道孙进程,并继续执行。

答案 1 :(得分:4)

因为它等待返回代码。您可以使用start命令创建一个单独的子进程:

@echo pre
@start "notepad" notepad
@echo post

答案 2 :(得分:1)

我从NT 3.1开始使用Windows,当你只输入程序名称(而不是使用START命令)时,我也会说“cmd.exe不会等待GUI程序终止”。虽然内存越来越暗淡,但我相信它最初是以这种方式运作的。但今天,我的声明是互动的,对于“批处理”文件是错误的。因此被提醒,我模糊地认为它是故意改变的,因为天真的批处理作者需要顺序执行,但我不能确定,我不知道什么时候。

答案 3 :(得分:0)

我认为答案就在于这个问题Difference between Windows and Console application

我引用两个答案。

康拉德鲁道夫回答说:

  

唯一的区别是,如果控制台应用程序未从一个控制台启动(或者在启动时主动抑制控制台),则控制台应用程序始终生成控制台。另一方面,Windows应用程序不会生成控制台。它仍然可以连接到一个existant控制台或使用AllocConsole创建一个新控制台。

     

这使Windows应用程序更适合GUI应用程序或后台应用程序,因为您通常不希望为这些应用程序创建终端窗口。

oefe回答:

  

从命令提示符以交互方式调用时,控制台和Windows应用程序的行为会有所不同:

     

启动控制台应用程序时,在控制台应用程序退出之前,命令提示符不会返回。当您启动Windows应用程序时,该命令立即返回。

     

批处理文件不是这样;他们将一直等到申请退出。

cmd和批处理之间的这种行为的差异使你认为它之前有用。