Я работаю над приложением (разработанным в Qt 5.11, набор инструментов MSVS2017 64bit), которое в какой-то момент должно будет выполнить сценарий .bat. Этот сценарий .bat вызовет определенную программу с соответствующими аргументами строки cmd. Скрипт и программа будут находиться в одном каталоге. Эта программа может требовать, а может и не требовать от пользователя нажатия Enter в конце. Если программа требует, чтобы пользователь нажал Enter, программа никогда не завершится, если символ новой строки не будет записан в stdin.
Я хочу проверить, ожидает ли программа ввода пользователя, прежде чем пытаться записать на свой стандартный ввод, если возможно, используя только библиотеку Qt.
Сценарий .bat просто вызовет программу:
Program arg1 arg2 arg3...
Из приложения сценарий будет выполняться с использованием QProcess:
Добавлен сплим после старта процесса
QProcess process;
process.setWorkingDirectory("C:/path/to/script");
process.start("cmd /C C:/path/to/script/script.bat");
QThread::sleep(someTimeout); // give enough time for process to finish
if (/*somehow*/ process.isWaitingForInput())
proces.write("\n");
process.waitForFinished();
process.readAllStandardOutput();
process.readAllStandardInput();
proces.exitCode();
Я нашел аналогичный вопрос с ответом, указывающим на MSDN WaitForInputIdle.
В будущем возможен перенос на Linux или Mac, и если это возможно, я бы хотел избежать
#if defined(WIN32)
WaitForInputIdle(...)
#else
PosixAlternative(...)
#endif
Кроме того, возможно, по теме, но мне любопытно, можно ли выполнить сценарий .bat из QProcess таким образом, чтобы окно cmd / terminal отображалось вместе с выводом std?
Я не уверен, что имеет смысл проверять, ожидает ли дочерний процесс ввода пользователя - во-первых, потому что я не верю, что есть какой-либо реалистичный способ сделать это, а во-вторых, потому что в этом нет необходимости - любые данные, которые вы write()
в QProcess будет буферизован и прочитан дочерним процессом, если / когда он попытается прочитать из stdin. (Дочерний процесс по определению будет выполняться асинхронно относительно вашего собственного процесса, поэтому любой подход, основанный на знании того, что дочерний процесс «делает в настоящее время», по своей сути является подозрительным, поскольку то, что дочерний процесс в настоящее время делает, может измениться и будет изменяться без уведомления со стороны одно мгновение в другое, прежде чем ваш процесс успеет среагировать)
То, что вы делаете жестяная банка (если хотите), - это чтение потоков stdout и / или stderr дочернего процесса и реакция на вывод дочернего процесса. (например, если вы знаете, что дочерний процесс в какой-то момент распечатает enter your decision now ->
в stdout, вы можете прочитать данные stdout из канала StandardOutput QProcess и отреагировать соответствующим образом, когда увидите эту строку)
Читая ваш ответ, я заметил, что не добавил сна после запуска процесса. Я знаю, что эта программа продлится какое-то время. Если после старта засыпают, программе будет предоставлено достаточно времени, чтобы завершить свою работу. Также я забыл упомянуть, что программа не должна требовать никаких входных данных. Но может потребоваться, чтобы пользователь нажал Enter в начале и после этого (как если бы мы добавляли pause
в сценарий .bat).
Тот факт, что я мог написать что-то для обработки стандартного ввода до того, как процесс прочитал его, уже решает мою проблему.
Ваш вопрос сильно отличается от stackoverflow.com/questions/6911498/…