C++ Получение вывода UTF-8 из CreateProcess()

Я не могу заставить его работать, поэтому я получаю вывод UTF-8 от CreateProcess() в wstring,

В настоящее время я использую этот метод, но без вывода UTF-8:

HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_ERR_Rd = NULL;
HANDLE g_hChildStd_ERR_Wr = NULL;

PROCESS_INFORMATION CreateChildProcess(void);
void ReadFromPipe(PROCESS_INFORMATION);

string run(char *command){
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    if ( ! CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &sa, 0) ) {
        exit(1);
    }
    if ( ! SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0) ){
        exit(1);
    }
    if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0) ) {
        exit(1);
    }
    if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ){
        exit(1);
    }
    char *szCmdline=command;
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;
    bool bSuccess = FALSE;
    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = g_hChildStd_ERR_Wr;
    siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    bSuccess = CreateProcess(NULL,
        szCmdline,     // command line
        NULL,          // process security attributes
        NULL,          // primary thread security attributes
        TRUE,          // handles are inherited
        CREATE_NO_WINDOW,             // creation flags
        NULL,          // use parent's environment
        NULL,          // use parent's current directory
        &siStartInfo,  // STARTUPINFO pointer
        &piProcInfo);  // receives PROCESS_INFORMATION
    CloseHandle(g_hChildStd_ERR_Wr);
    CloseHandle(g_hChildStd_OUT_Wr);
    if ( ! bSuccess ) {

        exit(1);
    }
    DWORD dwRead;
    CHAR chBuf[BUFSIZE];
    bool bSuccess2 = FALSE;
    std::string out = "", err = "";
    for (;;) {
        bSuccess2=ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
        if( ! bSuccess2 || dwRead == 0 ) break;

        std::string s(chBuf, dwRead);
        out += s;
    }
    dwRead = 0;
    for (;;) {
        bSuccess2=ReadFile( g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
        if( ! bSuccess2 || dwRead == 0 ) break;

        std::string s(chBuf, dwRead);
        err += s;
    }

    return out;
}

Я попробовал несколько вещей, но мне не удалось заставить его работать.

Любая помощь приветствуется!

1 ответ

Вывод команды - поток байтов. Таким образом, вы читаете это как поток байтов. Это две программы, чтобы договориться о кодировке для использования.

Например:

  • Если вы запускаете консольное приложение.NET (C#/VB.NET), приложение может использовать Console.OutputEncoding, чтобы установить кодировку Console.Write[Line] метод будет использовать.

    Console.OutputEncoding = Text.Encoding.UTF8;
    
  • Точно так же сценарий PowerShell может использовать [Console]::OutputEncoding, чтобы установить кодировку Write-Output или же Write-Host Командлеты будут использовать.

    [Console]::OutputEncoding = [Text.Encoding]::UTF8
    
  • cmd.exe или командный файл может использовать chcp командование

    chcp 65001
    
  • Приложение Win32 может использовать SetConsoleOutputCP Функция устанавливает свою выходную кодировку, если она использует WriteConsole, Если приложение использует WriteFile, просто нужно записать байты, закодированные как нужно (например, используя WideCharToMultiByte).

    SetConsoleOutputCP(CP_UTF8);
    

Когда вы затем читаете выходные данные приложения, вы декодируете поток байтов, используя согласованную кодировку. Например, используя MultiByteToWideChar функция

Другие вопросы по тегам