等到一个程序完成后再在 Windows 脚本中开始下一个程序
Posted
技术标签:
【中文标题】等到一个程序完成后再在 Windows 脚本中开始下一个程序【英文标题】:Wait till one program is finished before starting next in Windows Script 【发布时间】:2018-08-29 07:47:26 【问题描述】:我必须在指定目录的所有子目录中找到卸载程序。一旦找到卸载程序,我需要运行它。
@setlocal enabledelayedexpansion
@for /r %%i in ( un*.exe) do (
@echo Found file: %%~nxi
%%i
)
我已经能够使用上面的代码搜索子目录并在其中找到卸载程序。
问题: 命令%%i
执行uninstaller.exe
,控件立即返回命令提示符。由于控制立即返回到命令提示符,for-loop
的下一次迭代被执行,因此下一个卸载程序(通过命令%%i
)也被启动。
我需要什么:我想留在for-loop
的当前迭代中,直到由命令%%i
启动的卸载程序完成。
PS:卸载程序不会自行完成。他们要求几个选项,因此,我想一个一个地启动它们(这样用户就不会感到困惑)。
PS-2:正如下面其中一个 cmets 中指出的那样,PowerShell 可以解决这个问题,所以我也在寻找来自 PowerShell 社区的更多建议。
【问题讨论】:
一般来说,这可能无法解决。虽然您应该能够等待您启动的程序退出,但不能保证它不会通过启动 另一个 进程或在操作系统中安排一些活动来完成其工作,其中任何一个可能会比您启动的程序的生命周期更长。 例如卸载程序可能只是一个薄垫片,它只是启动适当的msiexec
进程来执行卸载,然后自行退出。
@Damien_The_Unbeliever:在我的情况下,卸载程序会要求几个选项,并且一旦启动就不会自行完成。
@Damien_The_Unbeliever,如果我们被限制在 CMD 脚本中,这并不容易解决。但在其他使用 Job 对象的语言中,这通常不是问题,例如 PowerShell 的 start-process
和 wait
选项。
@eryksun:如果可以解决问题,我可以灵活地使用 PowerShell。
【参考方案1】:
假设您想要 1) 在特定路径及其子目录中找到所有名为 un*.exe
的文件,2) 执行每个文件,以及 3) 在执行下一个可执行文件之前等待每个可执行文件完成,您可以编写类似这在 PowerShell 中:
Get-ChildItem "C:\Uninstaller Path\un*.exe" -Recurse | ForEach-Object
Start-Process $_ -Wait
【讨论】:
我用调试器逐步完成了这个过程,虽然它创建了暂停的进程,但它实际上在调用AssignProcessToJobObject
之前调用了ResumeThread
。这是错误的,PowerShell 团队中的某个人应该修复它。也就是说,我构建了一个测试可执行文件,它会立即生成另一个进程并退出。孙子进程在 10 次重复测试中没有逃脱 Job。一个警告是 OP 使用的是 Windows 7,它不允许嵌套的 Job 对象,因此在 Windows 7 中,PowerShell 本身不应该分配给 Job(例如,任务计划程序在 Job 中运行任务)。【参考方案2】:
您可以使用start /wait
。比较以下两行:
for %%i in (*.txt) do notepad "%%i"
for %%i in (*.txt) do start /wait notepad "%%i"
第一个会在几个记事本中打开所有匹配的文件,第二个只会在你关闭前一个记事本时打开下一个记事本。
【讨论】:
我已经尝试使用start
,但随后它会抛出错误Windows cannot find C:\Program
。我要启动的文件类型是.exe
。我也尝试使用start "" %%i
,但这也没有用。
那是因为路径中有空格。行情可以解决这个问题。这只是如何做到这一点的一个例子。对于EXE,当然使用start /wait "" "%%i"
(空字符串""
是伪标题,因为start
将第一个引用的参数作为标题)
@eryksun:我知道这种说法,但并非总是如此。试试我的例子。两者:有些 EXE 可以,有些不可以。
@eryksun:确实 - 在批处理文件中它等待,在命令行,它没有。 :/
@aschipfl,没有在批处理脚本中,如果不使用 start
,CMD 将等待(经典)calc.exe,就像它等待它在 中运行的所有程序一样脚本。新的 Windows 10 calc.exe“应用程序”非常不同,更像是 OP 的当前问题,即启动另一个进程或将请求传递给已经运行的实例然后立即退出的程序。无论如何,这个答案是错误的。它被编写为脚本(循环变量的转义百分比),然后声明对于批处理脚本来说是完全错误的。无论如何,这对 OP 的问题没有帮助。以上是关于等到一个程序完成后再在 Windows 脚本中开始下一个程序的主要内容,如果未能解决你的问题,请参考以下文章