从CreateProcess()中获取UTF-8输出

C++ Getting UTF-8 output from CreateProcess()

本文关键字:获取 UTF-8 输出 CreateProcess      更新时间:2023-10-16

我不能使它工作,所以我从CreateProcess()得到UTF-8输出到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;
}

我尝试了几种方法,但都没有成功。

任何帮助都是感激的!

命令的输出为字节流。所以你把它读成字节流。这取决于两个程序对使用的编码达成一致。

例如:

  • 如果你执行一个。net (c#/VB.NET)控制台应用程序,应用程序可以使用Console.OutputEncoding,来设置Console.Write[Line]方法将使用的编码。

    Console.OutputEncoding = Text.Encoding.UTF8;
    
  • 类似地,PowerShell脚本可以使用[Console]::OutputEncoding来设置Write-OutputWrite-Host cmdlet将使用的编码。

    [Console]::OutputEncoding = [Text.Encoding]::UTF8
    
  • cmd.exe或批处理文件可以使用chcp命令

    chcp 65001
    
  • Win32应用程序可以使用SetConsoleOutputCP函数来设置其输出编码,如果它正在使用WriteConsole。如果应用程序正在使用WriteFile,它只需要写入已经编码的字节(例如使用WideCharToMultiByte)。

    SetConsoleOutputCP(CP_UTF8);
    

当读取应用程序输出时,使用商定的编码解码字节流。例如使用MultiByteToWideChar函数