无法从Win7中的主批处理文件顺序运行多个批处理文件

时间:2013-07-27 23:48:45

标签: batch-file

我有一堆批处理文件,每个文件都会启动一堆可执行文件来同时运行。每个批处理文件启动30个可执行文件当这30个完成后,我希望下一批可执行文件再次运行30次。 .exe是使用批处理文件中的“start”命令调用的,它们工作得很好 - 我可以为每组30个exe运行单独的批处理文件,它们可以同时运行。

我创建了一个“主”批处理文件,它调用每个子批处理文件,但我无法弄清楚如何让它按顺序运行子批处理文件,等待一个文件在开始下一个之前完成。

如果主批处理文件是这样的:

Batch1.bat
Batch2.bat
Batch3.bat

然后只调用第一个批处理文件 - 其他文件永远不会被调用。

如果主批处理文件是这样的:

call Batch1.bat
call Batch2.bat
call Batch3.bat

然后所有的子批处理文件同时开始运行,我得到数百个可执行文件试图同时启动。

如何让主批处理文件调用第一个批处理文件,等待它完成,然后调用下一个,等待它完成,然后调用下一个,等等?

提前致谢,

rgames

6 个答案:

答案 0 :(得分:2)

当启动另一个批处理时,CALL将在同一窗口中启动它,并且被调用的批处理可以访问相同的变量上下文。所以它也可以改变影响调用者的变量。

在批处理文件中使用wait来调用可执行文件将等待它们退出。

START /WAIT  batch1.bat
START /WAIT batch2.bat

希望这有帮助

答案 1 :(得分:2)

对不起。我觉得这里有一个误解。如果您的主批处理文件是这样的:

call Batch1.bat
call Batch2.bat
call Batch3.bat

然后在Batch1.bat结束后调用Batch2.bat,依此类推。你可以做一个小测试来证实这一点。另一方面,每个BatchN.bat程序可能使用相同的变量吗?如果是这样,那么Batch1.bat中剩下的最后一个值可能会干扰Batch2.bat,依此类推。在这种情况下,您必须在每个批处理文件的开头添加Setlocal命令。

答案 2 :(得分:2)

我必须为几个文件运行数据导出程序。我的解决方案:

MasterBatch.bat:

@echo off
start /w batch1.bat
start /w batch2.bat

Batch1.bat

@echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo1"
EXIT

Batch2.bat

@echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo2"
EXIT

它可能适用于运行程序其他问题。

答案 3 :(得分:0)

您必须创建一个信令机制来识别EXE completation。

我会创建一个第三级批处理来运行每个EXE,在执行EXE之前创建临时文件并在之后删除它。

在子批次中,我会等到没有更多的临时文件。

所以,初始批次:

call Batch1.bat
call Batch2.bat
call Batch3.bat

子批次:

Set Index=0
Call :Exec exefile1 args ...
Call :Exec exefile2 args ...
...
:WaitAll
If Exist %Temp%\RUNNING_EXE.*.TMP GoTo :WaitAll
GoTo :EOF

:Exec
Set /A Index+=1
Echo %Index% > %Temp%\RUNNING_EXE.%Index%.TMP
Start Batch_3rd.BAT %*
GoTo :EOF

最后,第3级批处理,Batch_3rd.BAT:

%*
Del %Temp%\RUNNING_EXE.%Index%.TMP

%*是从子批处理(exe +参数)传递的参数,%Index%是正确的,因为start在创建时从子批处理复制环境,而子批处理没有改变这个副本。 最后一点:您可以将所有批次合并到一个批处理文件中,递归调用它。

答案 4 :(得分:0)

我的解决方案:

1) 我有四个批处理文件: Parent.bat和Batch1.bat,Batch2.bat,Batch3.bat

2) Parent.bat包含以下行(请仔细注意):

调用Batch1.bat> result1.log

致电Batch2.bat> result2.log

调用Batch3.bat> result3.log

3) 确保"进入每个子批处理文件的末尾",你有一个echo语句。 在这个echo语句之后,不应该是任何代码......

说Batch1.bat文件的内容是:

echo begin

robocopy" C:\ Users \ DD \ Documents \ A" " C:\用户\ DD \文件\ B"

echo end

echo this_is_the_last_line

答案 5 :(得分:0)

只是为了测试,我将使用简单的子批次(所有这些都是相同的)

@echo off
    for /l %%a in (1 1 5) do start "" notepad.exe

和一个主批处理文件

@echo off
    setlocal enableextensions disabledelayedexpansion

    set "flagFile=%temp%\%random%%random%%random%.tmp"

    for %%a in ( "batch1.cmd" "batch2.cmd" "batch3.cmd" ) do (
        call :startBatch %%a "%flagFile%"
    )

:retryClean
    echo %time% waiting for last batch to end
    2>nul ( 9>"%flagFile%" break ) || ( >nul timeout 5 & goto :retryClean )
    del /q "%flagFile%"

    echo DONE
    pause
    goto :eof

:startBatch batchFile flagFile
    echo %time% waiting to start "%~1"
    2>nul ( 9>"%~2" call "%~1" ) || ( >nul timeout 5 & goto :startBatch )
    echo %time% [ "%~1" ] STARTED
    goto :eof

此代码使用活动重定向(使用用户可用流9)启动每个子批次到临时标志文件。这将锁定标志文件,直到从子批处理开始的所有进程都已结束,因为在创建进程期间继承了重定向。

我们所要做的就是继续尝试使用相同的重定向启动下一个批处理文件:

  • 如果文件仍处于锁定状态(进程正在运行),则无法启动批处理文件,等待5秒钟并再次重试

  • 如果文件未锁定,则可以创建重定向并启动下一个批处理文件。