Как сделать, чтобы в WinAPI stdout перенаправлялся, а stderr уходил в никуда? Хочу запускать через каналы WinAPI программу, которая слегка «срёт» в stderr. Потому хочу, чтобы поток stderr уходил в никуда, а stdout — в именованный канал.
В структуре STARTUPINFO есть один бит — STARTF_USESTDHANDLES. Можно ли сделать так, чтобы один из этих трёх дескрипторов был нулевым, или буфер опустошался при переполнении, или что-то ещё — но только чтобы программа не останавливалась, если буфер переполнится?
ПОВТОРЯЮ ДЛЯ СИСАДМИНОВ. Программирование! Windows API! CreateProcess!
Я знаю, что такое 2>nul. И какой админ заменил «среднюю» сложность на «простую»: WinAPI — в принципе не тривиальная штука.

21 Авг 2019 в 06:21
168 +1
1
Ответы
1

Для перенаправления stdout в именованный канал и игнорирования stderr в WinAPI при запуске процесса с помощью CreateProcess, вам необходимо установить соответствующие дескрипторы файлов в структуре STARTUPINFO. Для этого вы можете использовать функцию CreatePipe для создания анонимного канала и затем использовать его для установки дескрипторов stdout и stderr.

Пример кода:

#include <windows.h>
#include <iostream>
int main() {
HANDLE outRead, outWrite;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
if (!CreatePipe(&outRead, &outWrite, &sa, 0)) {
std::cerr << "Error creating pipe" << std::endl;
return 1;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.hStdOutput = outWrite;
si.hStdError = NULL; // устанавливаем stderr в NULL, чтобы игнорировать сообщения
si.dwFlags = STARTF_USESTDHANDLES;
// Здесь указываете путь к запускаемому исполняемому файлу
if (!CreateProcess(NULL, "your_program.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
std::cerr << "Error creating process" << std::endl;
return 1;
}
// Чтение из именованного канала stdout
char buffer[4096];
DWORD bytesRead;
while (ReadFile(outRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
std::cout.write(buffer, bytesRead);
}
CloseHandle(outRead);
CloseHandle(outWrite);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}

В данном примере stdout будет перенаправлен в именованный канал, а stderr будет игнорироваться. Помните, что вам нужно заменить "your_program.exe" на путь к вашей программе, которую вы хотите запустить.

20 Апр в 13:19
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 92 436 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир