从批处理文件在新窗口中启动批处理文件,并在完成后使新窗口保持打开状态



编辑:我会尽量更清楚地说明我真正想要什么。

我有一些很长的批处理文件,我想按顺序运行,并且仅在前一个完成后才开始。

我正在尝试使用主批处理文件控制它

我希望他们在自己的窗口中启动每个窗口,该窗口在完成后保持打开状态,以便以后回顾

按数字顺序排列:

1.运行主批处理文件

2.打开新的CMD窗口

3.运行批处理文件 1

4.等待1完成

5.1 完成,保持窗口打开

6.打开另一个新的cmd窗口

7.运行批处理2 等

--原文留言 --

嗨,我有一个 Windows 批处理文件,需要按顺序运行其他 Windows 批处理文件并等待它们完成,然后再开始下一个。

像这样:

@echo off
setlocal EnableDelayedExpansion

SET RUN="C:first.bat"
start /wait cmd /c %RUN%
SET RUN="C:second.bat"
start /wait cmd /c %RUN%

例如,第一个和第二个只是回显以下内容:

@echo off
echo 1st
exit /b 0

当我运行它时,它会在新窗口中启动第一个脚本,并在完成后保持窗口打开,但要继续第二个脚本,我必须关闭新的cmd窗口。

如何在不关闭第一个.bat cmd 窗口的情况下使主批处理脚本启动第二个.bat?

谢谢

这是一个非常不寻常的要求

  1. 其他批处理文件不应由处理主批处理文件的cmd.exe实例处理,而应由其他cmd.exe实例处理,以便将其输出放在不同的控制台窗口中,并且
  2. 完成批处理文件的处理后,保持彼此命令进程运行,以便能够在其控制台窗口中查看其输出,并且
  3. 等待主批处理文件的进一步处理,直到启动的单独命令进程
  4. 完成批处理文件的处理,但不要等待启动的其他命令进程终止。

Windows 命令处理器cmd.exe不是为批处理文件的序列化多处理而设计的,批处理文件具有自身的多个实例,最终应继续运行。

但是,这里有三个批处理文件,它们证明了这是可能的,后面将解释一个缺点。

主.bat

@echo off & goto Main
:WaitForBatch
start "Run %~nx1" %ComSpec% /D /S /K "(%ComSpec% /D /C "%~1") & title Finished %~n1"
echo Waiting for finished execution of "%~nx1" ...
:CheckBatchRun
%WaitCommand% >nul
%SystemRoot%System32tasklist.exe /NH /FI "IMAGENAME eq cmd.exe" /V | %SystemRoot%System32find.exe /I "%~nx1" >nul
if errorlevel 1 goto :EOF
goto CheckBatchRun
:Main
setlocal EnableExtensions DisableDelayedExpansion
title Run %~nx0
if exist %SystemRoot%System32timeout.exe (
set "WaitCommand=%SystemRoot%System32timeout.exe /T 1"
) else (
set "WaitCommand=%SystemRoot%System32ping.exe 127.0.0.1 -n 2"
)
call :WaitForBatch "%~dp0First.bat"
call :WaitForBatch "%~dp0Second.bat"
title Finished %~n0
pause
endlocal

第一.bat

@echo off
dir %SystemRoot% /B /S

第二.bat

@echo off
dir %SystemRoot%*.exe
echo(
pause

Main.bat的编码方式是期望First.batSecond.batMain.bat位于同一目录中,但其他批处理文件也可以位于不同的目录中。执行三个批处理文件时的当前目录可以是任何目录。

Main.bat首先为自己设置执行环境,即:

  1. 命令回显模式关闭并
  2. 已启用命令扩展,并且
  3. 禁用延迟扩展。

cmd.exe处理Main.bat的控制台窗口的窗口标题被修改为在开头显示Run Main.bat

接下来确定命令超时是否可用,在这种情况下,此命令将在以后用于一秒的延迟(Windows Vista 和更高版本的 Windows 客户端版本),或者是否必须将命令PING用于一秒钟的延迟(Windows XP)。

然后第一次使用批处理文件调用子例程WaitForBatchFirst.bat

子例程使用命令START在窗口标题Run First.bat的新控制台窗口中启动另一个命令进程,同时忽略 Windows 默认不存在的AutoRun注册表字符串值。

第二个cmd.exe实例在执行完接下来使用其他参数指定的命令行后继续运行。第二个cmd.exe的命令行需要再次执行第三个cmd.exe,忽略AutoRun注册表字符串值(如果存在)以执行使用完全限定文件名指定的批处理文件First.bat。第三个cmd.exe实例在完成批处理文件的处理时关闭自身。

第二个cmd.exe现在将其控制台窗口的标题更改为Finished First。重要的是,窗口标题中不再有批处理文件扩展名。

第一个cmd.exe实例处理Main.bat在成功启动第二个cmd.exe后继续批处理文件处理。它使用该命令等待一秒钟,然后运行TASKLIST以输出所有正在运行的cmd.exe进程,其中包含详细的信息,这些信息被重定向到命令FIND以搜索不区分大小写的批处理文件名First.bat

只要有一个cmd.exe进程运行First.bat,第一个cmd.exe就会继续在循环中对子例程WaitForBatchMain.bat进行批处理文件,并跳转到CheckBatchRun。否则,子例程将保留,Main.bat的处理继续进行,WaitForBatch的第二个CALLSecond.bat.

最后,Main.bat还将其窗口标题更改为Finished Main,并提示用户在Windows资源管理器中双击此文件开始执行的情况下Main.bat按任意键。

First.bat需要很长时间才能完成,因为必须将数千个文件名输出到第二个cmd.exe的控制台窗口中。可以单击标题为Run First.bat的控制台窗口的X符号立即终止第二个和第三个cmd.exe的执行,这会导致第一个cmd.exe继续启动另外两个cmd.exe来处理Second.bat

也可以通过按Ctrl+C并使用Y回答终止批处理作业的提示(在英语 Windows 上)来中断长时间运行的First.bat,导致第三个cmd.exe真正停止处理First.bat和第二个cmd.exe继续运行,显示First.bat的输出并将其控制台窗口的窗口标题更改为Finished First。这是通过首先cmd.exe处理Main.bat检测到的,并开始处理Second.bat

此解决方案的缺点是,在标题为Run First.bat的控制台窗口中按Ctrl+C时,DIR输出所有文件名,现在按N(在英语 Windows 上)仍会导致批处理作业终止。我不是 100% 确定为什么会发生这种情况。我对这种行为只有一个假设。

要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,然后完整而仔细地阅读每个命令的显示帮助页面。

  • call /?
  • cmd /?
  • dir /?
  • echo /?
  • endlocal /?
  • find /?
  • goto /?
  • if /?
  • pause /?
  • ping /?
  • setlocal /?
  • start /?
  • tasklist /?
  • timeout /?
  • title /?

为每个辅助批次 2 使用早期命令(每行一行)构造主批次 1 窗口标题:

任务列表/FI"窗口标题均衡器<批处理>" |在某个地方查找 "cmd.exe"> NUL & GOTO

以上行的操作顺序相反 = 最后一批首先列出

然后:

  1. 启动主批次 1
  2. 需要时启动批次 2 并退出批次 1
  3. 批次 2 中的最后一个命令: 启动主批次 1 & cmd/k
  4. 根据需要重复

最新更新