C++ 从 CreateProcess() 获取 UTF-8 输出

2024-01-09

我无法让它工作,所以我得到 UTF-8 输出CreateProcess() into 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 https://learn.microsoft.com/en-us/dotnet/api/system.console.outputencoding,设置编码Console.Write[Line] method https://learn.microsoft.com/en-us/dotnet/api/system.console.write将使用。

    Console.OutputEncoding = Text.Encoding.UTF8;
    
  • 同样,PowerShell 脚本可以使用[Console]::OutputEncoding,设置编码Write-Output https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-output or Write-Host https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-hostcmdlet 将使用。

    [Console]::OutputEncoding = [Text.Encoding]::UTF8
    
  • The cmd.exe或者批处理文件可以使用chcp command https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/chcp.

    chcp 65001
    
  • Win32 应用程序可以使用SetConsoleOutputCP功能 https://learn.microsoft.com/en-us/windows/console/setconsoleoutputcp设置其输出编码,如果它使用WriteConsole https://learn.microsoft.com/en-us/windows/console/writeconsole。如果应用程序正在使用WriteFile https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile,它只需要写入已经根据需要编码的字节(例如使用WideCharToMultiByte https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte).

    SetConsoleOutputCP(CP_UTF8);
    

然后,当您读取应用程序输出时,您可以使用约定的编码对字节流进行解码。例如。使用MultiByteToWideChar功能 https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 从 CreateProcess() 获取 UTF-8 输出 的相关文章

随机推荐