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

21 Авг 2019 в 06:21
199 +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 Апр 2024 в 13:19
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир