Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
1 / 1 / 3
Регистрация: 17.09.2015
Сообщений: 29

Чтение stdout дочернего процесса

07.08.2018, 20:44. Показов 2074. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача:
запустить консольную утилиту и отобразить процесс ее деятельности.

Пример:
pngout.exe screen.png 1.png

При запуске, выше указанной строчки, в командной строке последовательно отображается процент и информация о сжатии.

Все примеры которые я пробовал( с именными и не именными пайпами) возвращают мне stdout только по окончанию дочернего процесса. А мне нужно получать эти данные последовательно, что бы я мог делать вывод информации о работе дочернего процесса аналогично как в командной строке.

Вопрос:
Возможно ли это сделать? И если да, то как?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.08.2018, 20:44
Ответы с готовыми решениями:

Создание дочернего процесса
Уважаемые форумчане, у меня возник такой вопрос: Возможно ли средствами с++ создать дочерний процесс для определенного процесса? так...

Создание дочернего процесса
нужно создать дочерний процесс, чтобы если закрыть родительский закрылся и дочерний. но незнаю как можно сделать...

Ожидание завершения дочернего процесса
Привет всем. Задание работы заключается в написании двух программ: главной и дочерней. Главная программа должна запускать дочернюю и...

2
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
08.08.2018, 18:49
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
 
// Проверка запуска под Windows NT.
bool IsWinNT()
{
    OSVERSIONINFO osv;
    osv.dwOSVersionInfoSize = sizeof(osv);
    GetVersionEx(&osv);
    return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
 
// Вывод подробной информации об ошибке.
void ErrorMessage(const char *str)
{
    LPVOID msg;
    
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Язык по умолчанию.
        (LPTSTR)&msg,
        0,
        NULL
    );
    
    fprintf(stderr, "%s: %s\n", str, msg);
    LocalFree(msg);
}
 
 
int main(int argc, char *argv[])
{
    char buf[1024]; // Буфер ввода/вывода.
    
    STARTUPINFO si;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd; // Структура security для пайпов.
    PROCESS_INFORMATION pi;
    
    HANDLE newstdin, newstdout, read_stdout, write_stdin; // Дескрипторы пайпов.
    
    if (IsWinNT()) // Инициализация security для Windows NT.
    {
        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(&sd, true, NULL, false);
        sa.lpSecurityDescriptor = &sd;
    }
    else
        sa.lpSecurityDescriptor = NULL;
    
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = true; // Разрешаем наследование дескрипторов.
    
    if (!CreatePipe(&newstdin, &write_stdin, &sa, 0)) // Создаем пайп для stdin.
    {
        ErrorMessage("CreatePipe");
        getch();
        return 1;
    }
    
    if (!CreatePipe(&read_stdout, &newstdout, &sa, 0)) // Создаем пайп для stdout.
    {
        ErrorMessage("CreatePipe");
        getch();
        CloseHandle(newstdin);
        CloseHandle(write_stdin);
        return 1;
    }
    
    GetStartupInfo(&si); // Создаем startupinfo для дочернего процесса.
    
    /*
    Параметр dwFlags сообщает функции CreateProcess как именно надо создать процесс.
    STARTF_USESTDHANDLES управляет полями hStd*.
    STARTF_USESHOWWINDOW управляет полем wShowWindow.
    */
    
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout; // Подменяем дескрипторы для
    si.hStdInput = newstdin; // Дочернего процесса.
    
    char app_spawn[] = "C:\\Windows\\System32\\cmd.exe";
    
    // Создаем дочерний процесс.
    if (!CreateProcess(app_spawn, NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        ErrorMessage("CreateProcess");
        getch();
        CloseHandle(newstdin);
        CloseHandle(newstdout);
        CloseHandle(read_stdout);
        CloseHandle(write_stdin);
        return 1;
    }
    
    unsigned long exit = 0; // Код завершения процесса.
    unsigned long bread; // Кол-во прочитанных байт.
    unsigned long avail; // Кол-во доступных байт.
    
    memset(buf, 0, sizeof(buf));
    
    for(;;) // Основной цикл программы.
    {
        GetExitCodeProcess(pi.hProcess, &exit); // Пока дочерний процесс не закрыт.
        if (exit != STILL_ACTIVE)
            break;
        
        PeekNamedPipe(read_stdout, buf, 1023, &bread, &avail, NULL);
        
        // Проверяем, есть ли данные для чтения в stdout.
        if (bread != 0)
        {
            memset(buf, 0, sizeof(buf));
            if (avail > 1023)
            {
                while (bread >= 1023)
                {
                    ReadFile(read_stdout, buf, 1023, &bread, NULL); // Читаем из пайпа stdout.
                    printf("%s", buf);
                    memset(buf, 0, sizeof(buf));
                }
            }
            else
            {
                ReadFile(read_stdout, buf, 1023, &bread, NULL);
                printf("%s", buf);
            }
        }
        
        if (kbhit()) // Проверяем, введено ли что-нибудь с клавиатуры.
        {
            memset(buf, 0, sizeof(buf));
            *buf = (char)getche();
            
            WriteFile(write_stdin, buf, 1, &bread, NULL); // Отправляем это в stdin
            
            if (*buf == '\r')
            {
                *buf = '\n';
                printf("%c", *buf);
                WriteFile(write_stdin, buf, 1, &bread, NULL); // Формирум конец строки, если нужно.
            }
        }
    }
    
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(newstdin); 
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);
    return 0;
}

Оригинал Использование anonymous pipes для перехвата StdIn/StdOut дочернего процесса
1
222 / 19 / 0
Регистрация: 15.08.2016
Сообщений: 47
12.10.2020, 19:56
Код оригинала содержит ошибки. Смотрите по ссылке, в комментариях.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.10.2020, 19:56
Помогаю со студенческими работами здесь

Управление видимостью дочернего процесса
Здравствуйте. Консольное приложение можно сделать скрытым или видимым, например, так: #include &lt;WS2tcpip.h&gt; int main() { ...

Корректное завершение дочернего процесса
Я тестирую оконную программу - открываю и закрываю её несколько раз. Иногда программа завершается с ошибкой. Мне надоело запускать и...

Завершение дочернего процесса по ошибке
Например, я запускаю дочерний процесс 1.ехе и ожидаю его окончания: #include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace...

Получить код завершения дочернего процесса
Можно ли в материнском процессе получить с каким кодом завершился дочерний процесс? Добавлено через 20 секунд cout &lt;&lt;...

Остановка дочернего процесса по его ошибке
В текущей директории имеется файл code.exe, которй принимает два числа и выводит их сумму. Например, скомпилированнй из такого: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru