! | Данная информация предназначена только только для 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(
CreatePipe было бы не обязательно и было бы все проще если достаточно собрать результаты в файл. https://groups.google.com/forum/#!topic/microsoft.public.vc.language/koxom1CKD74
Но тогда потенциально необходимая интерактивная передача stdin на вход остается проблемой.
http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx
! | Лучше избегать вообще системных пайпов везде, где можно применить наши более надежные средства межпроцессной коммуникации |
Верное наблюдение Чена что можно все подвесить причем не заметить проблемы на небольших объемах данных.
Пока не актуально в наших применениях. В случае необходимости подавать stdin надо учитывать потребность в тридах или иной файловой ассинхронности.
Остается проблема выдачи процесса в процессе чтения пайпа. В черное окно при таком перехвате уже ничего не идет.
Bat-файл просто прерывается и в перехваченном тексте нет сообщений что там произошло. Stderr еще отдельная проблема.