Как мне дождаться завершения серии командных файлов, прежде чем продолжить выполнение моего кода? - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть серия из 15 пакетных файлов, которые мне нужно запустить как часть сценария powershell.В настоящее время у меня есть рабочая версия этого, но я выполняю каждый пакетный файл, как показано ниже:

Start-Process -FilePath "Script1.bat" -WorkingDirectory "C:\Root" -Wait
Start-Process -FilePath "Script2.bat" -WorkingDirectory "C:\Root" -Wait
Start-Process -FilePath "Script3.bat" -WorkingDirectory "C:\Root" -Wait

и т. Д.

Пакетные файлы объединяют тысячи сценариев SQL в один большой сценарийи некоторые из них намного медленнее других (SQL заполняет 5 разных баз данных, а 1 намного больше, чем другие 4)

Я пытаюсь повысить скорость выполнения 15 сценариев, и яЯ подумал, что хорошей идеей будет запускать пакетные файлы параллельно, чтобы все файлы SQL создавались одновременно, а не последовательно.Для этого я удалил «-Wait» и вижу, что все окна командной строки открываются одновременно.

Проблема, с которой я столкнулся, заключается в том, что после создания файлов SQL я используюCopy-Item для перемещения скриптов в нужное место.Поскольку команды Copy-Item больше не ждут выполнения пакетных файлов, они пытаются скопировать файлы SQL из папки, в которой они созданы, до того, как пакетные файлы закончили их создавать.

Так что в основном я 'Я пытаюсь найти способ «Подождать» запуска коллекции пакетных файлов, чтобы я мог убедиться, что пакетные файлы завершены, прежде чем я начну копировать файлы.Я смотрел онлайн целую вечность и пытался использовать powershell Jobs с командой «Wait-Job», но ожидание ждет только до тех пор, пока не будет выполнен каждый пакетный файл, а не до тех пор, пока они не будут завершены.У кого-нибудь есть идеи о том, как этого можно достичь?

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Я думаю: поместите все объекты процесса в массив ... и подождите, пока все они завершатся ...

$p = 1..15 | ForEach-Object {
    Start-Process -FilePath "Script$_.bat" -WorkingDirectory "C:\Root" -PassThru
}

while(($p.HasExited -eq $false).Count) {
    Start-Sleep -Milliseconds 100
}
0 голосов
/ 15 декабря 2018

Я бы использовал здесь событие.

Вместо запуска пакета с тем, что у вас есть, попробуйте следующее:

$bat3 = Start-Process -FilePath "Script3.bat" -WorkingDirectory "C:\Root" -Wait -PassThru

Обратите внимание, вы сохраняете объект процесса впеременная, и вы добавили параметр -PassThru (таким образом, объект возвращается командлетом).Затем создайте блок сценария с тем, что вы хотите, чтобы после завершения пакетного сценария:

$things-todo-when-batchfile-completes = {
    Copy-Item -Path ... -Destination ...
    Get-EventSubscriber | Unregister-Event
}

Обязательно завершите блок с помощью Get-EventSubscriber | Unregister-Event.Затем создайте обработчик событий:

$job = Register-ObjectEvent -InputObject $bat3 `
-eventname exited `
-SourceIdentifier Batch3Handler `
-Action $things-todo-when-batchfile-completes

Теперь, когда задача завершится, обработчик выполнит действия в $things-todo-when-batchfile-completes.

Это должно позволить вам запустить пакетные файлы,и когда они заканчивают работать, вы запускаете копию файла, которую вы искали.

У Microsoft есть запись в блоге о технике, описанной в статье Сценарий выходного дня: игра с процессами и событиями PowerShell .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...