Как cmd.exe отображает стандартный вывод, даже если процесс не сбрасывается? - PullRequest
2 голосов
/ 28 октября 2019

Я использовал этот код MSDN для перехвата stdout и stderr для дочернего процесса (за исключением того, что сначала я вызываю PeekNamedPipe, чтобы не блокировать), и все хорошо, за исключением того, что дляstdout, если процесс не сбрасывается, тогда я не вижу результат процесса сразу. Кажется, что Stderr автоматически сбрасывается при отправке чего-либо на него, но stdout буферизирует результаты.

Внезапно я поражаюсь, что процесс оболочки cmd.exe может печатать результаты сразу, когда вы выполняете код в Visual Studio. Я бы тоже так хотел. Как это сделать?

Ответы [ 3 ]

0 голосов
/ 28 октября 2019

cmd.exe использует прямые вызовы winapi WriteFile или WriteConsoleW для печати на стандартный вывод. поэтому, если вы хотите сделать это тоже - вы также можете использовать этот winapi.

, когда стандартный вывод является файлом:

enter image description here

когда стандартный выводконсольный: enter image description here

0 голосов
/ 29 октября 2019

Мы не можем выяснить, как Visual Studio реализует эту логику.

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

for (;;)
{
    bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
    if (!bSuccess || dwRead == 0) break;

    bSuccess = WriteFile(hParentStdOut, chBuf,
        dwRead, &dwWritten, NULL);
    if (!bSuccess) break;

    // Check if there is more data to read, if not break.
    if (dwRead < BUFSIZE)
        break;
}
0 голосов
/ 28 октября 2019

Это не cmd.exe, а реализация stdio. При печати в стандартный вывод он хранит информацию в буфере и периодически сбрасывает ее (или перед выключением) другим потоком. Такое поведение специально и используется для повышения производительности. В противном случае печать будет блокироваться.

Вот как сделать автоматическую очистку после каждой команды печати: C автоматическая очистка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...