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

Mar*_*ryl 11 batch-file

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

很少有很多参考文献,特别是来自SO/SE:

而且,我自己记得这是/是真的.

但它似乎没有这种方式.

我在一个简单的批处理文件上测试过这个:

echo Pre
notepad
echo Post
Run Code Online (Sandbox Code Playgroud)

Post不打印,直到我关闭记事本.为什么,当记事本显然是一个GUI应用程序?

我在Windows 8,7和XP上测试了这个,只是为了排除在最新版本的Windows中行为发生了变化的可能性.我试图将命令扩展禁用为可能的罪魁祸首之一.

Jam*_* L. 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 使用`start`启动程序(不带`/ wait`选项)会改变CMD处理器的行为.它不是等待进程在继续之前终止,而是继续.如果你不使用`start`,它将一直等到它启动的程序终止.永远不会等待孙子进程终止.它只监视它自己创建的直接子进程. (2认同)

npo*_*aka 4

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

@echo pre
@start "notepad" notepad
@echo post
Run Code Online (Sandbox Code Playgroud)

  • 好吧,但你没有抓住我问题的重点。你说的不应该是真的,检查我的问题中的参考文献。它们都涉及如何使批处理等待进程完成(就好像它实际上没有完成一样)。 (2认同)