Win32: определить, является ли дескриптор stdout символом или потоком wchar - PullRequest
3 голосов
/ 11 марта 2009

Я пишу утилиту win32 для нашего продукта, которая должна вызывать произвольную программу через оболочку и регистрировать ее вывод. Мы делаем это путем перенаправления stdout из дочернего процесса в канал:

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0);

    // Redirect the first process stdout to our write pipe
    // so that we can read its output from the read pipe.
    startUpInfo.dwFlags = STARTF_USESTDHANDLES;
    startUpInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    startUpInfo.hStdOutput = hWritePipe;
    startUpInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);

    CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo[i], &procInfo);

Существует множество программ, которые можно назвать так, многие из которых не находятся под нашим контролем. В настоящее время мы видим проблему, когда вывод многих программ обрезается после первого символа - обычно верный признак того, что строка WCHAR по ошибке используется в качестве CHAR.

Как я могу определить, пишет ли дочерний процесс в свой стандартный поток данных как CHAR или WCHAR?

Ответы [ 2 ]

3 голосов
/ 11 марта 2009

Суть в том, что нет 100% надежного способа сделать это. Дескрипторы ввода / вывода процесса не являются специфическими для кодирования. Они просто оперируют потоком байтов. Для процесса вполне возможно на некоторое время написать ASCII и переключиться на Unicode позже.

К сожалению, невозможно из потока байтов с 100% точностью определить, что лежит в основе кодирования. Единственный способ определить это - иметь протокол рукопожатия, в котором процесс сообщает вам, какую кодировку он будет использовать. Вероятно, не вариант в этом случае.

Ссылки по теме

1 голос
/ 11 марта 2009

Я думаю, что вы должны договориться об этом при подключении. Вы можете использовать PeekNamedPipe () и угадывать, основываясь на том, выглядит ли он как символ Юникода ...

...