Re[2]: Работа с консоль-приложением из Windows оболочки
От: mein Молдова http://people.overclockers.ru/mein
Дата: 20.04.06 08:21
Оценка:
Извиняюсь что поднял древнюю тему. Выше приведённый код у меня работает несколько неправильно. Сначала приведу:

void CQueue::OnBnClickedButton1()
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    HANDLE hRead, hWrite;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0))
        MessageBox(L"error create pipe");

    STARTUPINFO si;
    memset(&si, 0, sizeof(si));

    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdOutput = NULL;
    si.hStdError = hWrite;

    PROCESS_INFORMATION pi; 
    memset(&pi, 0, sizeof(pi));

    if (!CreateProcess(L"xxx.exe",L" --xxx", NULL, NULL,
        TRUE, CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi))
        MessageBox(L"error create process");

    CloseHandle(hWrite);  // <--

    char xxx[1000];
    DWORD dd;
    while(ReadFile(hRead,xxx,400,&dd,0))
    {
        printbuffer(IDC_LIST1,xxx,dd);
    }    
    CloseHandle( pi.hProcess ); //  А надо ли? 
      CloseHandle( pi.hThread );  //  А надо ли?
}

void CQueue::printbuffer(int nID, char buf[], int kol){ // выводит построчно в ListBox данные
    wchar_t str[1000];
    CString edit;
    char tempbuf[1000]; 
      int pos=0;
    if(strlen(tbuf)){ // если с предыдущего буфера осталась незаконченая строка, то продолжим
        strcpy(tempbuf,tbuf);
        pos = (int)strlen(tempbuf);
    }
    for(int i=0;i<kol;i++){
        if(buf[i]==13){ // последняя найденная строка
            MultiByteToWideChar(CP_ACP,0,tempbuf,pos,str,1000);
            str[pos]=0; 
            pos=0; 
            ((CListBox*)GetDlgItem(nID))->AddString(str);
        }else{
            if(buf[i]==10)continue;
            tempbuf[pos++] = buf[i];
        }
    }
    if(pos>0){ // если буфер закончился, а строка не закончена, то запомним остатки до следующего буфера
        strncpy(tbuf,tempbuf,pos);
        tbuf[pos]=0;
    }
}

В общем проблема такая:
Иногда в листбокс попадают строки с различными добавками(слева) причём добавки берутся из предыдущих строк. Вот пример как должно быть
"12345 abcdfhgg"
"xxxxx 1/100"
"xxxxx 2/100"
А вот пример как получается:
"12345 abcdfhgg"
"123xxxxx 1/100"
"123xxxxx 2/100"
Причём добавки бывают разной длинны и необязательно ровно с предыдущей строки — бывает и с более ранних. На конфигурацию добавок напрямую влияет размер буфера (у меня в примере 400) — чем он больше тем меньше ошибочных строк, но из-за специфики программы я не могу его делать слишком большим. Ну а самое интересное то что если перед чтением из пайпа, поставить задержку(чтобы дождатся когда процесс завершится), то всё нормально читается и выводится. Эта особенность не даёт отладкой найти глюк — при отладке всё проходит шеколадно. Где я накосячил?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.