Я хочу сделать следование из сценария пакетной обработки Windows:
start proc1.exe
start proc2.exe
...
start procN.exe
<wait for all N processes to complete> <-- What do I put here?
Как я ожидаю всех порожденных процессов для завершения?
Это некрасиво, но вы можете заключить каждую команду в другой командный файл, который запускает команду и затем сигнализирует о ее завершении. Ваш основной пакетный файл будет вызывать каждый из этих пакетных файлов асинхронно и находиться в цикле, ожидая сигналов.
Например:
main.bat
start cmd /c proc1.bat
start cmd /c proc2.bat
:wait
sleep 1
IF NOT EXIST proc1done GOTO wait
IF NOT EXIST proc2done GOTO wait
del proc1done
del proc2done
echo All processes are complete
proc1.bat
proc1.exe
echo Done > proc1done
Команда сна доступна в Windows Server 2003 Resource Kit Tools . Если у вас его нет, вы можете использовать команду ping на localhost, чтобы замедлить этот жесткий цикл.
Вы могли бы сделать это, если бы вы написали код .NET или Win32 C / C ++ для запуска процессов, но нет способа сделать это в пакетном режиме. файл. Если вы используете start
для асинхронного запуска proc1.exe, не существует пакетной команды, которая позволяла бы вернуться позже и дождаться ее завершения.
Но вы можете легко сделать это на одном из языков сценариев, предназначенных для пакетной работы, Python, WSH и т. Д.
Например, вот простой сценарий, использующий Windows Script Host . WSH включен во все версии Windows, начиная с Windows 98 . Так что этот скрипт должен работать где угодно.
Этот сценарий запускает две программы и ожидает их завершения. Сохраните его как start2.wsf
. Затем просто используйте его в своем командном файле:
start2.wsf "prog1.exe" "prog2.exe"
<package>
<job id="Start 2 Procs">
<runtime>
<description>Start 2 programs and wait for them both to finish.
</description>
<unnamed
name="program"
helpstring="the program to run"
many="false"
required="2"
/>
<example>
Example: Start2.wsf "cl -c foo.obj" "cl -c bar.obj"
</example>
</runtime>
<script language="JScript">
if (WScript.Arguments.length < 2)
{
WScript.Arguments.ShowUsage();
WScript.Quit();
}
var proc1 = WScript.Arguments.Unnamed.Item(0);
var proc2 = WScript.Arguments.Unnamed.Item(1);
var Shell = WScript.CreateObject("WScript.Shell");
var oProc1 = Shell.Exec(proc1);
var oProc2 = Shell.Exec(proc2);
while (oProc1.Status == 0 && oProc2.Status == 0)
{
WScript.Sleep(1000);
}
</script>
</job>
</package>