从批处理文件开始一个新的 window 的批处理文件,并在完成后保持新的 window 打开
Starting a batch file in a new window from a batch file, and keeping the new window open after completion
编辑:我会尽量使我真正想要的更清楚。
我有一些非常长的批处理文件,我想按顺序 运行 并且只在前一个完成后才开始。
我正在尝试使用主批处理文件来控制它
我希望他们各自开始 window 完成后保持打开状态以供稍后回顾
数字顺序:
1.run 主批处理文件
2.open 新命令 window
3.run批处理文件1
4.waiting 1 完成
5.1 完成,保持window打开
6.open 另一个新命令 window
7.run批次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
当我 运行 这样做时,它会在新的 window 中启动第一个脚本,并在完成后保持 window 打开状态,但要继续我的第二个脚本关闭新命令 window.
如何在不关闭 first.bat cmd window 的情况下让主批处理脚本启动 second.bat?
谢谢
这是一个非常不寻常的要求
- 其他批处理文件不应由处理主批处理文件的
cmd.exe
实例处理,而应由 cmd.exe
的其他实例处理,只是为了在不同的控制台中输出它们 window和
- 在完成批处理文件的处理后,保持彼此的命令进程 运行 以便能够在他们的控制台中查看他们的输出 windows 和
- 等待主批处理文件的进一步处理,直到启动的单独命令进程完成批处理文件的处理,但不要等待启动的其他命令进程终止。
Windows 命令处理器 cmd.exe
不是为序列化 multi-processing 批处理文件而设计的,它具有多个自身实例,最终应该保持 运行.
但是,这里有三个批处理文件证明这是可能的,但有一个缺点稍后会解释。
Main.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%\System32\tasklist.exe /NH /FI "IMAGENAME eq cmd.exe" /V | %SystemRoot%\System32\find.exe /I "%~nx1" >nul
if errorlevel 1 goto :EOF
goto CheckBatchRun
:Main
setlocal EnableExtensions DisableDelayedExpansion
title Run %~nx0
if exist %SystemRoot%\System32\timeout.exe (
set "WaitCommand=%SystemRoot%\System32\timeout.exe /T 1"
) else (
set "WaitCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
)
call :WaitForBatch "%~dp0First.bat"
call :WaitForBatch "%~dp0Second.bat"
title Finished %~n0
pause
endlocal
First.bat
@echo off
dir %SystemRoot% /B /S
Second.bat
@echo off
dir %SystemRoot%\*.exe
echo/
pause
Main.bat
的编码方式要求 First.bat
和 Second.bat
与 Main.bat
在同一目录中,但其他批处理文件也可以在不同的目录中。三个批处理文件的当前执行目录可以是任意目录。
Main.bat
首先为自己设置执行环境为:
- 命令回显模式关闭并且
- 命令扩展已启用并且
- 禁用延迟扩展。
cmd.exe
处理Main.bat
的控制台window的window标题修改为开头显示Run Main.bat
。
下一步确定命令TIMEOUT是否可用,在这种情况下,稍后将使用此命令延迟一秒(Windows Vista 及更高版本Windows 客户端版本)或者如果命令 PING 必须用于一秒延迟(Windows XP)。
然后使用批处理文件 First.bat
.
第一次调用子例程 WaitForBatch
子例程使用命令 START 在新控制台中启动另一个命令进程 window with window title Run First.bat
with ignoring AutoRun
注册表字符串值 Windows 默认不存在。
第二个 cmd.exe
实例在使用其他参数执行下一个指定的命令行完成后保留 运行。第二个 cmd.exe
的命令行需要再次执行第三个 cmd.exe
并忽略 AutoRun
注册表字符串值(如果存在)以执行完全限定指定的批处理文件 First.bat
文档名称。第三个 cmd.exe
个实例在批处理文件处理完成后自行关闭。
第二个 cmd.exe
现在将其控制台的标题 window 更改为 Finished First
。重要的是批处理文件扩展名不再出现在 window 标题中。
第一个 cmd.exe
实例处理 Main.bat
在第二个 cmd.exe
成功启动后继续批处理文件处理。它使用命令等待一秒钟,然后运行 TASKLIST 输出所有 运行 cmd.exe
进程的详细信息,这些信息被重定向到命令 FIND 搜索 case-insensitive 批处理文件名 First.bat
。
只要有cmd.exe
进程运行First.bat
,第一个cmd.exe
继续子程序Main.bat
内部的批处理文件[=24] =] 在循环中跳转到 CheckBatchRun
。否则子例程将离开,Main.bat
的处理继续进行 WaitForBatch
的第二个 CALL 和 Second.bat
。
最后 Main.bat
也将其 window 标题更改为 Finished Main
并提示用户按任意键以防 Main.bat
双击开始执行Windows 资源管理器中的此文件。
First.bat
需要很长时间才能完成,因为必须将数千个文件名输出到第二 cmd.exe
的控制台 window 中。可以单击标题为 Run First.bat
的控制台 window 的 X 符号立即终止第二个和第三个 cmd.exe
的执行,结果首先 cmd.exe
继续开始另外两个 cmd.exe
用于处理 Second.bat
.
也可以通过按Ctrl+C中断长运行First.bat
,并用[=回答终止批处理作业的提示147=]Y(英文 Windows)导致第三个 cmd.exe
真正停止 First.bat
的处理,第二个 cmd.exe
保持 运行 显示First.bat
的输出并将其控制台 window 的 window 标题更改为 Finished First
。这是由第一个 cmd.exe
处理 Main.bat
检测到的,它开始处理 Second.bat
。
此解决方案的缺点是,在控制台 window 中按 Ctrl+C 时标题为 Run First.bat
而 DIR 输出所有文件名,现在按 N(英文 Windows)仍然会导致批处理作业终止。我不是 100% 确定为什么会这样.我对这种行为只有一个假设。
为了了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
cmd /?
dir /?
echo /?
endlocal /?
find /?
goto /?
if /?
pause /?
ping /?
setlocal /?
start /?
tasklist /?
timeout /?
title /?
编辑:我会尽量使我真正想要的更清楚。
我有一些非常长的批处理文件,我想按顺序 运行 并且只在前一个完成后才开始。
我正在尝试使用主批处理文件来控制它
我希望他们各自开始 window 完成后保持打开状态以供稍后回顾
数字顺序:
1.run 主批处理文件
2.open 新命令 window
3.run批处理文件1
4.waiting 1 完成
5.1 完成,保持window打开
6.open 另一个新命令 window
7.run批次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
当我 运行 这样做时,它会在新的 window 中启动第一个脚本,并在完成后保持 window 打开状态,但要继续我的第二个脚本关闭新命令 window.
如何在不关闭 first.bat cmd window 的情况下让主批处理脚本启动 second.bat?
谢谢
这是一个非常不寻常的要求
- 其他批处理文件不应由处理主批处理文件的
cmd.exe
实例处理,而应由cmd.exe
的其他实例处理,只是为了在不同的控制台中输出它们 window和 - 在完成批处理文件的处理后,保持彼此的命令进程 运行 以便能够在他们的控制台中查看他们的输出 windows 和
- 等待主批处理文件的进一步处理,直到启动的单独命令进程完成批处理文件的处理,但不要等待启动的其他命令进程终止。
Windows 命令处理器 cmd.exe
不是为序列化 multi-processing 批处理文件而设计的,它具有多个自身实例,最终应该保持 运行.
但是,这里有三个批处理文件证明这是可能的,但有一个缺点稍后会解释。
Main.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%\System32\tasklist.exe /NH /FI "IMAGENAME eq cmd.exe" /V | %SystemRoot%\System32\find.exe /I "%~nx1" >nul
if errorlevel 1 goto :EOF
goto CheckBatchRun
:Main
setlocal EnableExtensions DisableDelayedExpansion
title Run %~nx0
if exist %SystemRoot%\System32\timeout.exe (
set "WaitCommand=%SystemRoot%\System32\timeout.exe /T 1"
) else (
set "WaitCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
)
call :WaitForBatch "%~dp0First.bat"
call :WaitForBatch "%~dp0Second.bat"
title Finished %~n0
pause
endlocal
First.bat
@echo off
dir %SystemRoot% /B /S
Second.bat
@echo off
dir %SystemRoot%\*.exe
echo/
pause
Main.bat
的编码方式要求 First.bat
和 Second.bat
与 Main.bat
在同一目录中,但其他批处理文件也可以在不同的目录中。三个批处理文件的当前执行目录可以是任意目录。
Main.bat
首先为自己设置执行环境为:
- 命令回显模式关闭并且
- 命令扩展已启用并且
- 禁用延迟扩展。
cmd.exe
处理Main.bat
的控制台window的window标题修改为开头显示Run Main.bat
。
下一步确定命令TIMEOUT是否可用,在这种情况下,稍后将使用此命令延迟一秒(Windows Vista 及更高版本Windows 客户端版本)或者如果命令 PING 必须用于一秒延迟(Windows XP)。
然后使用批处理文件 First.bat
.
WaitForBatch
子例程使用命令 START 在新控制台中启动另一个命令进程 window with window title Run First.bat
with ignoring AutoRun
注册表字符串值 Windows 默认不存在。
第二个 cmd.exe
实例在使用其他参数执行下一个指定的命令行完成后保留 运行。第二个 cmd.exe
的命令行需要再次执行第三个 cmd.exe
并忽略 AutoRun
注册表字符串值(如果存在)以执行完全限定指定的批处理文件 First.bat
文档名称。第三个 cmd.exe
个实例在批处理文件处理完成后自行关闭。
第二个 cmd.exe
现在将其控制台的标题 window 更改为 Finished First
。重要的是批处理文件扩展名不再出现在 window 标题中。
第一个 cmd.exe
实例处理 Main.bat
在第二个 cmd.exe
成功启动后继续批处理文件处理。它使用命令等待一秒钟,然后运行 TASKLIST 输出所有 运行 cmd.exe
进程的详细信息,这些信息被重定向到命令 FIND 搜索 case-insensitive 批处理文件名 First.bat
。
只要有cmd.exe
进程运行First.bat
,第一个cmd.exe
继续子程序Main.bat
内部的批处理文件[=24] =] 在循环中跳转到 CheckBatchRun
。否则子例程将离开,Main.bat
的处理继续进行 WaitForBatch
的第二个 CALL 和 Second.bat
。
最后 Main.bat
也将其 window 标题更改为 Finished Main
并提示用户按任意键以防 Main.bat
双击开始执行Windows 资源管理器中的此文件。
First.bat
需要很长时间才能完成,因为必须将数千个文件名输出到第二 cmd.exe
的控制台 window 中。可以单击标题为 Run First.bat
的控制台 window 的 X 符号立即终止第二个和第三个 cmd.exe
的执行,结果首先 cmd.exe
继续开始另外两个 cmd.exe
用于处理 Second.bat
.
也可以通过按Ctrl+C中断长运行First.bat
,并用[=回答终止批处理作业的提示147=]Y(英文 Windows)导致第三个 cmd.exe
真正停止 First.bat
的处理,第二个 cmd.exe
保持 运行 显示First.bat
的输出并将其控制台 window 的 window 标题更改为 Finished First
。这是由第一个 cmd.exe
处理 Main.bat
检测到的,它开始处理 Second.bat
。
此解决方案的缺点是,在控制台 window 中按 Ctrl+C 时标题为 Run First.bat
而 DIR 输出所有文件名,现在按 N(英文 Windows)仍然会导致批处理作业终止。我不是 100% 确定为什么会这样.我对这种行为只有一个假设。
为了了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
cmd /?
dir /?
echo /?
endlocal /?
find /?
goto /?
if /?
pause /?
ping /?
setlocal /?
start /?
tasklist /?
timeout /?
title /?