В. Как приостановить PowerShell при выполнении процесса Win32 из Windows PowerShell, чтобы завершить процесс, прежде чем запускать другие команды PowerShell?
О. В этом можно убедиться, запустив программу Notepad: она выполняется, но управление немедленно передается в окно PowerShell.
При запуске консольного приложения PowerShell ожидает завершения консольного приложения, прежде чем продолжить работу. Таким образом, чтобы дождаться завершения процесса Win32, можно направить выход процесса в null, например, так:
notepad | out-null
При запуске этой команды управление не возвращается PowerShell до тех пор, пока пользователь не закроет экземпляр Notepad.
Другой способ: использовать метод Process.WaitForExit, чтобы PowerShell дожидался завершения процесса. Для этого необходимо получить ссылку на идентификатор процесса Win32, которого нужно дождаться. Идентификатор процесса можно попытаться получить, выполнив поиск имени процесса с помощью таких критериев, как заголовки окна (например, $tpid = get-process | where {$_.mainwindowtitle -match "notepad"}), но при этом могут возникать ошибки, если выполняется несколько процессов с одинаковым именем. Более удачный способ -- создать процесс с использованием метода start класса System.Diagnostics.Process в Microsoft .NET Framework, который возвращает идентификатор процесса при создании последнего, как в следующем примере:
PS C:UsersAdministrator> $tpid = [diagnostics.process]::start("notepad.exe")
PS C:UsersAdministrator> $tpid.WaitForExit()
После этого управление не будет возвращено PowerShell до тех пор, пока не будет закрыт экземпляр Notepad. Альтернатива предыдущему способу -- объединить команды в одну, например так:
[diagnostics.process]::start("notepad.exe").WaitForExit()
С использованием Process.WaitForExit можно также ввести максимальное время ожидания (в миллисекундах). Например, при запуске $tpid.WaitForExit(30000) ожидание длится до завершения процесса или 30 с (в зависимости от того, какое из этих событий произойдет первым). Если процесс закрывается в заданный период времени, то Process.WaitForExit возвращает значение TRUE; в противном случае возвращается значение FALSE.
Обратите внимание: если нужно передать параметры в процесс Win32, достаточно добавить их ко второму аргументу команды start. Например, чтобы запустить Notepad для редактирования файла c: empjohn.txt, можно использовать команду
[diagnostics.process]::start("notepad.exe","C: empjohn.txt").WaitForExit()
При этом необходимо указать полный путь к каждому параметру. Если нужно использовать только текущую рабочую папку, просто введите $pwd.