11

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

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

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

然而,它似乎并没有以这种方式工作。

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

echo Pre
notepad
echo Post

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

我已经在 Windows 8、7 和 XP 上对此进行了测试,只是为了排除这种行为在最新版本的 Windows 中发生变化的可能性。我也尝试禁用命令扩展作为可能的罪魁祸首之一。

4

4 回答 4

10

它与您启动的应用程序如何运行和终止有关。一些程序启动另一个进程然后终止,其他程序继续运行。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 将立即打开,Notepad.exe 将在您关闭 MSPaint.exe 的第二个实例之前打开。

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

于 2013-11-08T02:48:20.097 回答
4

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

@echo pre
@start "notepad" notepad
@echo post
于 2013-10-15T12:23:49.817 回答
1

我从 NT 3.1 开始使用 Windows,当您只需键入程序名称(而不是使用 START 命令)时,我也会说“cmd.exe 不会等待 GUI 程序终止”。虽然记忆变得模糊,但我相信它最初是这样工作的。但是今天,我的陈述在交互上是正确的,对于“批处理”文件是错误的。如此提醒后,我隐约认为它是故意更改的,因为天真的批处理编写器期望顺序执行,但我不能确定,也不知道什么时候。

于 2016-08-04T01:25:27.843 回答
0

我认为答案在于这个问题Windows 和控制台应用程序之间的区别

我引用两个答案。

康拉德鲁道夫回答:

唯一的区别是,如果控制台应用程序不是从一个控制台启动(或者控制台在启动时被主动抑制),它总是会生成一个控制台。另一方面,Windows 应用程序不会产生控制台。它仍然可以附加到现有控制台或使用 AllocConsole 创建一个新控制台。

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

oefe 回复:

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

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

这不适用于批处理文件;他们将一直等到应用程序退出。

cmd 和batch 之间的这种bahviour 差异使您认为它以前有效。

于 2016-01-24T14:17:09.767 回答