Ввод и вывод текста из долго работающего консольного приложения (C++)

У меня есть давно работающее консольное приложение, которое запускается с Windows или может быть запущено приложением, которое я пишу.

У меня был ограниченный успех при отправке ключей в консольное приложение, и я даже не знаю, с чего начать чтение вывода из него. Возможно ли чтение вывода из консольного приложения, которое даже не запущено запрашивающим приложением?

В любом случае, два вопроса...

Как я могу эмулировать клавишу «возврат»? (Вот что я должен отправить определенные ключи в приложение, и приложение действительно получает ключи, но я не могу найти, как эмулировать клавишу ENTER.

do {
    hwndCurrentWindow = FindWindowA("ConsoleWindowClass", "My Other Console App");
    if (hwndCurrentWindow == 0) {
        break;
    }

    iStringLen = GetWindowTextW (hwndCurrentWindow, wcharWindowText, 500);
    if (iStringLen == 0) {
        continue;
    }

    SetActiveWindow(hwndCurrentWindow);
    printf("Sending '?'");
    SendMessage(hwndCurrentWindow, WM_CHAR, '?', 0);
    // '?' shows up in console app
    printf("Sending 'a'");
    SendMessage(hwndCurrentWindow, WM_CHAR, 'a', 0);
    // 'a' shows up in console app.
    //printf("Sending RETURN");
    //SendMessage(hwndCurrentWindow, WM_CHAR, VK_RETURN, 0);
    // nothing happens
    break;
} while (hwndCurrentWindow);

Как я могу прочитать данные из консольного приложения? (Если бы другое консольное приложение не работало непрерывно, я бы просто записал вывод в файл и прочитал его... черт возьми, это все еще может работать)

Я рассмотрел несколько вариантов, но многие из тех, что я прочитал, предназначены для C#, и, к сожалению, я не могу позволить себе роскошь менять языки. Есть ли аналогичные варианты для C++?

Соберите вывод stdout из консольного приложения с помощью C++. один не работает, потому что приложение не закрывается. Так что он просто висит и ждет. Постоянное добавление в буфер.

Перехватывать консольный ввод-вывод

Захват исполняемого вывода C# из другой программы C#< /а>

Спасибо за любую помощь, которую вы можете предоставить!


person Kyle Johnson    schedule 06.07.2013    source источник


Ответы (1)


Вам необходимо перенаправить ввод/вывод из этого приложения в основное приложение. Вот статья об этом: Создание дочерний процесс с перенаправленным вводом и выводом

person Bogolt    schedule 06.07.2013
comment
Спасибо! Я видел еще одну статью MSDN (support.microsoft.com/kb/190351), любые мысли на том? - person Kyle Johnson; 06.07.2013
comment
В основном они делают одно и то же. Вам нужно внимательно следить за вызовом функции CreateProcess() и параметрами, которые нужно использовать. Вам нужно будет создать набор каналов, а затем указать их в CreateProcess(), чтобы они использовались для связи между вашим приложением и созданным вами процессом. Я уверен, что вы можете взять любой из примеров, чтобы получить нужные вам результаты. - person Bogolt; 06.07.2013
comment
Это действительно помогло! Я добился большого успеха. Я использовал PID, чтобы убить приложение, когда мое приложение завершает работу, и могу получить вывод из консольного приложения, но мне не удалось отправить какие-либо данные с помощью команды WriteToPipe. Даже предоставление действительного пути к файлу ничего не отправляет, я поставил в небольшой команде Sleep, чтобы убедиться, что она запущена, прежде чем пытаться отправить данные, или, возможно, я не вижу отправляемых данных, потому что не отправляется ENTER. Любые идеи о том, как отправить строку в канал g_hChildStd_IN_Wr? Или это канал g_hChildStd_IN_Rd?? Это используется один раз. Стена текста. - person Kyle Johnson; 09.07.2013
comment
Вам не нужно отправлять Enter, все, что вам нужно, это отправить данные в канал с одной стороны и получить их с другой стороны. Убедитесь, что дочернее приложение запущено (лучший способ проверки — заставить его работать бесконечно, всегда ожидая, пока что-то придет из канала), в приведенной выше ссылке есть хороший пример клиента. И согласно этой ссылке вам нужно использовать g_hChildStd_IN_Wr для записи в канал. - person Bogolt; 10.07.2013
comment
Я так и думал, поэтому попытался отправить \r\n или его вариант. Консольное приложение, которое запускается, в основном выдает некоторую информацию в STDOUT, а затем продолжает обновлять последнюю строку, ожидая ввода пользователя. Это блокирует раздел ReadFromPipe(). Кроме того, даже отправка текста через WriteToPipe, похоже, не помогает. Это очень расстраивает, но с каждым днем ​​я становлюсь немного ближе. - person Kyle Johnson; 10.07.2013
comment
Сначала вам нужно выяснить, какая часть вашего кода не работает должным образом. Это может быть отправляющая или принимающая сторона. Чтобы получить это - попробуйте использовать сторонние образцы (например, по ссылке выше) с вашими компонентами, чтобы вы знали, какая часть кода виновата. Затем вы можете просто свериться с образцами, чтобы найти, что именно вы делаете неправильно. - person Bogolt; 11.07.2013
comment
Да, я обнаружил, что приложение, в которое я пытаюсь отправить данные, использует ReadConsoleInput, поэтому мне приходится использовать какую-то версию ConsoleWrite. И сейчас я пытаюсь понять, как построить INPUT_RECORD так, как он будет создан. с помощью ReadConsoleInput, чтобы я мог отправить его в ConsoleWrite. - person Kyle Johnson; 11.07.2013