在异步方式下运行Windows批处理文件命令

214

比如说,我有以下几个exe文件:

  • foo.exe
  • bar.exe
  • baz.exe

我该如何在批处理文件中异步运行它们,即不等待前一个程序停止就运行下一个程序?

7个回答

285

使用START命令来运行每个程序应该可以得到您所需的内容:

START "title" [/D path] [options] "command" [parameters]

每个 START 调用都会执行其参数给定的命令并立即返回,除非使用了 /WAIT 开关进行执行。

这适用于命令行应用程序。没有命令行的应用程序无论如何都会立即返回,因此为确保异步运行所有应用程序,请使用START


1
好的,谢谢。我应该仔细阅读help的每个条目。 :) - RichN
3
不要介意我自己做广告:我曾经创建了一个批处理程序,可以作为某种线程池来运行进程:https://dev59.com/mXRB5IYBdhLWcg3wSVYI#676667 - Joey
5
如果需要提供参数或者命令路径中包含空格,请记得添加引号。此时,您还需要为打开的控制台窗口提供一个标题:start "" "[命令路径]" [命令参数]。 - Pierluigi
“没有命令行的应用程序无论如何都会立即返回” - 你确定吗?为什么GUI应用程序会阻止批处理文件? - Martin Prikryl

75

结合之前几个答案,你可以尝试 start /b cmd /c foo.exe

以一个简单的例子为例,如果你想打印出java/groovy/grails/gradle的版本,你可以在批处理文件中这样做:

@start /b cmd /c java -version
@start /b cmd /c gradle -version
@start /b cmd /c groovy -version
@start /b cmd /c grails -version

如果你有类似于进程探测器(Sysinternals)的工具,你会看到一些子 cmd.exe 进程,每个进程都有一个 java 进程(按照上面的命令)。输出将按照它们完成的顺序打印到屏幕上。

start /b :  Start application without creating a new window. The
             application has ^C handling ignored. Unless the application
             enables ^C processing, ^Break is the only way to interrupt
             the application

cmd /c : Carries out the command specified by string and then terminates

14
在批处理脚本中,有时候你会在开头看到 echo off,这个命令可以防止所有命令在控制台上显示。而 @ 符号的作用与此类似,但只针对单个命令。因此,有时你会看到 @echo off - djKianoosh
对我没用。仍然停在等待应用程序关闭之前,无法继续。 - user1853517

39
您可以使用“start”命令在不启动新窗口的情况下生成后台进程: start /b foo.exe 新进程将无法被 CTRL-C 打断;您只能使用 CTRL-BREAK(或关闭窗口或通过任务管理器)来终止它。

7
现在键盘上的“BREAK”键在哪里? - user2023370
1
@user2023370,仍然在使用暂停键。大多数缺少某些键的笔记本电脑支持隐藏的键组合 - Gerold Broser
1
@user2023370 现代键盘上的暂停/中断键 https://zh.wikipedia.org/wiki/Break%E9%94%AE#%E7%8E%B0%E4%BB%A3%E9%94%AE%E7%9B%98 - phuclv
对我无效。仍然停在等待应用程序关闭之前,无法继续。 - user1853517

26

创建一个包含以下行的批处理文件:

start foo.exe
start bar.exe
start baz.exe 

Start命令会在一个新窗口中运行你的命令,因此这3个命令会异步运行。


1
只要路径中没有空格,这个命令就可以正常工作。但是当你在路径两边加上双引号时,它会将其视为标题而不是应用程序。下面这个命令可以正常工作:START "VMPlayer" /D "C:\Users\gavin\Virtual Machines\CentOS 8 64-bit" "C:\Program Files (x86)\VMware\VMware Player\vmplayer.exe"。 - user1853517

19
使用 START 命令
start [programPath]

如果程序路径含有空格,请记得加上引号。在这种情况下,您还需要为打开的控制台窗口提供一个标题。

start "[title]" "[program path]"

如果您需要提供参数,请将它们附加在命令引号之外的末尾。

start "[title]" "[program path]" [list of command args]

使用/b选项可以避免打开新的控制台窗口(但在这种情况下,您无法使用CTRL-C来中断应用程序)。


11

还有第三个(可能更容易的)选项。如果您想要启动多个单个程序实例,使用类似于Unix风格命令处理器的Xargs或GNU Parallel可以使该过程变得相当简单。

有一个名为PPX2的Win32 Xargs克隆版,可以使这个过程变得非常简单。

例如,如果您想要转码视频文件目录,您可以运行以下命令:

dir /b *.mpg |ppx2 -P 4 -I {} -L 1 ffmpeg.exe -i "{}" -quality:v 1 "{}.mp4"

这段代码的作用是,dir /b *.mpg 获取当前目录下所有的 .mpg 文件列表,然后使用 | 运算符将该列表传递给 ppx2,ppx2 会构建一系列需要并行执行的命令;根据 -P 4,每次执行4个命令。使用 -L 1 告诉 ppx2 每次只向 ffmpeg 发送一个目录列表中的文件名。

接下来,你只需编写命令行 (ffmpeg.exe -i "{}" -quality:v 1 "{}.mp4"),其中 {} 会自动替换为目录列表中的每一行。

虽然不是每个场景都通用,但这比使用批处理文件更容易。当然,如果你不是在处理文件列表,也可以通过管道将文本文件或任何其他程序的内容传递到 pxx2 的输入中。


1
最新的xargs win32端口现在运行良好(无论是与git for windows一起提供的那个)。 - Peter M
这很棒,但它无法处理包含Unicode字符的文件。有支持Unicode文件的计划吗?谢谢。 - Gökhan Sever
@GökhanSever 过去我解决这个问题的方法是使用路径的“短名称”形式,看起来像 C:\PROGRA1\WINDOW3\MYPROG~1.EXE。虽然不太美观,但它能正常工作。 - moltenform

0

我无法让任何东西工作,最终只能使用PowerShell来启动批处理脚本..有时甚至使用start cmd /c也无法正常工作,不知道为什么..我甚至尝试了像start cmd /c notepad & exit这样的东西

start-Process "c:\BACKUP\PRIVATE\MobaXterm_Portable\MobaXterm_Portable.bat" -WindowStyle Hidden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接