How to asynchronously read the standard output stream and standard error stream at once

后端 未结 4 2012
终归单人心
终归单人心 2020-11-29 04:33

I want to read the ouput of a process in the form as is in a console (standard output is blended with standard error in one stream). Is there a way how to do it?

I w

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-11-29 05:23

    Similar kind of example, with exception that I'm collecting stdout and error into separate strings using StringBuilder for that purpose.

    /// 
    /// Executes command
    /// 
    /// command to be executed
    /// output which application produced
    /// true - if retain PATH environment variable from executed command
    /// true if process exited with code 0
    static bool ExecCmd(string cmd, out String output, bool transferEnvVars = false)
    {
        ProcessStartInfo processInfo;
        Process process;
    
        if (transferEnvVars)
            cmd =  cmd + " && echo --VARS-- && set";
    
        processInfo = new ProcessStartInfo("cmd.exe", "/c " + cmd);
        processInfo.CreateNoWindow = true;
        processInfo.UseShellExecute = false;
        processInfo.RedirectStandardError = true;
        processInfo.RedirectStandardOutput = true;
    
        process = Process.Start(processInfo);
    
        // Executing long lasting operation in batch file will hang the process, as it will wait standard output / error pipes to be processed.
        // We process these pipes here asynchronously.
        StringBuilder so = new StringBuilder();
        process.OutputDataReceived += (sender, args) => { so.AppendLine(args.Data); };
        StringBuilder se = new StringBuilder();
        process.ErrorDataReceived += (sender, args) => { se.AppendLine(args.Data); };
    
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        process.WaitForExit();
    
        output = so.ToString();
        String error = se.ToString();
    
        if (transferEnvVars)
        {
            Regex r = new Regex("--VARS--(.*)", RegexOptions.Singleline);
            var m = r.Match(output);
            if (m.Success)
            {
                output = r.Replace(output, "");
    
                foreach ( Match m2 in new Regex("(.*?)=([^\r]*)", RegexOptions.Multiline).Matches(m.Groups[1].ToString()) )
                {
                    String key = m2.Groups[1].Value;
                    String value = m2.Groups[2].Value;
                    Environment.SetEnvironmentVariable(key, value);
                }
            }
        }
    
        if(error.Length != 0)
            output += error;
        int exitCode = process.ExitCode;
    
        if (exitCode != 0)
            Console.WriteLine("Error: " + output + "\r\n" + error);
    
        process.Close();
        return exitCode == 0;
    }
    

提交回复
热议问题