Как PowerShell информирует об окончании выполнения команды?
Мы можем запустить Powershell (pwsh.exe) не только напрямую, но и через стандартную командную оболочку Windows и через новое приложение Windows Terminal. Их объединяет, то что они не позволяют ничего писать, пока не будет выполнена записанная ранее команда (если конечно она не запущена в фоновом режиме).
Я пишу программу на c#, которая должна работать с этим самым PowerShell через стандартные потоки ввода/вывода и я хочу добиться такого же поведения - программа должна каким-то образом информироваться о том, когда команда выполнена. Например выполняя Write-Host Hey1; Start-Sleep 10s; Write-Host Hey2 нельзя полагаться (да и понятно, что это не правильный способ) на наличие данных в выходном потоке.
Вроде бы приложение Windows Terminal в настройках профиля для PowerShell не смотря на обилие настроек по дизайну, непосредственно по подключению к нему имеет лишь одну - это путь до исполняемого файла pwsh.exe. Есть ощущение, что существует стандартный способ информирования об окончании выполнении команды, но я ни как не могу его правильно загуглить.
Пробовал гуглить так же и на английском, вышел на информацию об записываемом байте \a, но скорее всего это для информирования пользователя звуковым сигналом. В целом просматривал байты, которые pwsh.exe пишет в выходной поток, и среди управляющих там лишь 13 и 10 (перевод каретки и новая строка), есть еще 27, но он используется равномерно в тексте и судя по его смыслу ни как не связан с информированием об окончании выполнения.
Edit: я придумал, как на много понятнее сформулировать мой вопрос. Представьте вы хотите, чтобы пользователь в вашей программе на WPF или WinForms мог использовать консоль PowerShell, которая будет представлена например в виде textarea в которой будут выходные данные и text box, в который он сможет записывать команды и отправлять их по нажатию рядом стоящей кнопки.
Для этого запускается процесс PowerShell, в котором разрешено перенаправление потоков ввода/вывода. Эта программа на WinForms или WPF позволяет в любой момент нажать кнопку отправки команды, которая запишет команду из textbox во входной поток powershell.
Дело в том, что хочется добиться такого же поведения как в терминале Windows и оригинальной консоли PowerShell - вводить команду в них можно только когда предыдущая будет записана. Только в этом случае будет блокироваться например кнопка отправки команды, пока не будет выполнена предыдущая команда. Вот в этом вопрос, как понять, что предыдущая команда выполнилась?
Сергей, Всего скрипта - это получить сразу и Hey1 и Hey2 после 10 секунд ожидания
А отдельных команд - это получить Hey1, потом долго ничего не получать и потом получить Hey2
Судя по всему, вам нужен второй
Второй вариант предполагает, что вы команды запускаете и ожидаете вывода асинхронно, иначе от первого отличаться не будет ничем.
MaxKozlov,извиняюсь, все теперь понял вас. Мне на самом деле как раз нужен первый вариант. Сейчас асинхронно читаю поток побайтово, и как только что-то в него записывается я сразу это вывожу. Но проблема в том, что получив hey1, я не могу сказать будет ли за ним следовать hey2. Я же хочу, чтобы пользователь как в оригинальной консоли Powershell и терминале Windows мог вводить следующую команду, уже только когда предыдущая будет выполнена. А для этого, я должен получить видимо некоторое оповещение об этом.
Сергей, Ну если вы команды передаёте туда неинтерактивно(сразу всё скопом), то powershell никаких "признаков окончания" не выводит в поток.
тут, разве что, ждать перевод строки.
Если интерактивно - вы можете попробовать парсить приглашение (prompt PS ...>)
Всё ж использование натива выглядит перспективнее :)
Ну этот скоп команд, фактически ведь одна команда просто выполняемая в течении 10 секунд, и нужна она лишь, чтобы показать, что команда может выполняться долго и её выводит может происходить в разное время. Ведь хорошо, может быть в теории реально одна команда, но которая будет вести себя так-же, и как мне тогда понять, когда она завершилась? Я вас не очень понял, если не передавать скопом, то все же какой-то признак выводится, можете ли прояснить не много подробнее?
В любом случае при выполнении данного скопа команд в обычном Powersshell, ввод блокируется ровно до выполнения последней команды, вот именно такое поведение я и хочу сделать.
Парсить приглашение, конечно рассматривал такой вариант, но костыль как-то не красиво использовать.
И добавлю, может этот момент не совсем ясен, команды ну можно сказать будут поступать непрерывно, и от них ожидается результат. Я не много дополнил вопрос, может быть такой объяснение, более точно покажет, что я хочу сделать.
MaxKozlov, Я может не правильно делаю, что задаю вопрос в комментариях, но фактически он относится к этому и увы новый я создать не могу, лимит закончился) Позволяет ли использование runspace получить ответ в виде строки, а не в виде коллекции объектов PSObject ? Просто хочу понять, стоит ли копать в эту сторону
MaxKozlov, а можете еще уточнить по поводу цветов? Runspace ведь как раз не позволяет получить цвета, а просто выдает объекты PSObject, которые при помощи ToString() преобразуются в строки, не содержащие символов форматирования.
Сергей, в PSv7 цвета рисует консоль на основе всяких esc последовательностей (ANSI, тот самый код 27) если вы их видите в выводе после ToString() - значит они никуда не делись
Информация о раскраске-то где-то берётся. надо API посмотреть как реализовано, я не вчитывался
Вы вообще с консольного вывода как цвета берёте себе ?
MaxKozlov, честно говоря я не очень понимаю в какой момент они подтягиваются, но я беру текст из стандартного потока вывода и вывожу его в свою консоль. Так-же не много поразмышляв я кажется понял, что ищу не совсем ту вещь, может мне надо знать не когда завершилась та или иная команда, а когда от меня запрощен ввод данных. По большому результат один и тот же, как только команда завершилась, происходит запрос данных. Так как это уже совсем другой вопрос, я создал его отдельно
Сергей, Ну если вы вообще не очень понимаете откуда берётся цвет, оно у вас наверняка заработает и через runspace, возможно с добавкой format/out-string
Это отличный способ, который я пробовал, но есть не достаток - мне нужен именно, тот вывод, который представляет консоль PowerShell, то есть с форматированием и цветовыми кодами. Тесная интеграция с объектами PowerShell безусловно удобна, но в моем случае она не нужна.