Перенаправление stdin и stdout консольного процесса

  !   Данная информация предназначена только только для IT-специалистов по системной интеграции модулей БИОСОФТ-М. (см. Руководства пользователя к программным продуктам)

В Запуск и выгрузка параллельных процессов перенаправление включается x_bGrabProcessOutput и результат возвращается в ReadGrabbedProcessOutput().

Оригинальный код перенаправления пайпов из sys::GExecuteWmiScript() содержал массу проблем. Он не годен ни для чего кроме локального случая ограниченного применения для WMI скриптов PcInfo.

Подвисание если данных нет

Здесь

            if (
                !::ReadFile(
                    hRead,                  // Handle to the file to be read
                    szOutput,               // buffer that receives the data
                    C_nBufSize,             // Number of bytes to be read
                    (LPDWORD) &nBytesRead,   // the number of bytes read
                    NULL) // OVERLAPPED structure
                ||
                !nBytesRead)
            {
                break;
            }

все висит ожидая поступления в stdout от запущенного процесса. Если такое не поступит то зависание навсегда.

Решение из http://stackoverflow.com/questions/11396870/how-can-i-tell-if-there-is-new-data-on-a-pipe

        // Check if there is some data in the pipe first!
        DWORD nPending = 0;
        if (!PeekNamedPipe(
                _m_hStdReadRedirect,
                0,
                0,
                0,
                &nPending,
                0))
        {
            rFAIL("pipe failed");
            break;
        }
//VL.

и если данных нет и процесс завершен то тогда все заканчивается, иначе ждем дальше:

//VL: 2014-03-28
        if (nPending <= 0)
        {
            // break on dead process
            if (!IsProcessAlive() || IsProcessComplete())
            {
                break;
            }
 
            // yeld to the busy child process
            sys::GSleepInTicks(10);
        }
//VL.
        else
        {
//VL: 2014-03-28
            // !
            nBytesRead = 0;
//VL.
 
            if (
                !::ReadFile(
Вывод в файл вместо pipe

CreatePipe было бы не обязательно и было бы все проще если достаточно собрать результаты в файл. https://groups.google.com/forum/#!topic/microsoft.public.vc.language/koxom1CKD74

Но тогда потенциально необходимая интерактивная передача stdin на вход остается проблемой.

Deadlock stdin/stdout и проблема ограниченности буферов pipe

http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx

 !  Лучше избегать вообще системных пайпов везде,
где можно применить наши более надежные
средства межпроцессной коммуникации

Верное наблюдение Чена что можно все подвесить причем не заметить проблемы на небольших объемах данных.

Пока не актуально в наших применениях. В случае необходимости подавать stdin надо учитывать потребность в тридах или иной файловой ассинхронности.

Выдача прогресса

Остается проблема выдачи процесса в процессе чтения пайпа. В черное окно при таком перехвате уже ничего не идет.

Не перехватываются сообщения об ошибках

Bat-файл просто прерывается и в перехваченном тексте нет сообщений что там произошло. Stderr еще отдельная проблема.