Определите, ожидает ли QProcess пользовательского ввода - PullRequest
0 голосов
/ 31 октября 2018

Я работаю над приложением (разработанным в Qt 5.11, набор инструментов MSVS2017 64bit), которое в какой-то момент должно будет выполнить скрипт .bat. Этот скрипт .bat вызывает определенную программу с соответствующими строковыми аргументами cmd. Скрипт и программа будут находиться в одном каталоге. Эта программа может требовать или не требовать от пользователя нажатия Enter в конце. Если программа требует, чтобы пользователь нажал Enter, программа никогда не завершит работу, если в строке ввода не будет введен символ новой строки.

Я хочу проверить, ожидает ли программа ввода данных от пользователя, прежде чем пытаться записать в свой стандартный ввод, если это возможно, используя только библиотеку 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 / терминала отображалось вместе с выводом std?

1 Ответ

0 голосов
/ 31 октября 2018

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

То, что вы можете сделать (если хотите), это прочитать потоки stdout и / или stderr дочернего процесса и отреагировать на выходные данные дочернего процесса. (например, если вы знаете, что в какой-то момент дочерний процесс будет выводить enter your decision now -> в стандартный вывод, вы можете прочитать данные stdout из канала StandardOutput QProcess и реагировать соответствующим образом, когда увидите эту строку)

...