예제 #1
0
    public static ProcessOutput StartProcess(string fileName, string command, string workingDir = null, int timeoutMiliSeconds = 0)
    {
        var startinfo = new System.Diagnostics.ProcessStartInfo();

        startinfo.FileName               = fileName;
        startinfo.UseShellExecute        = false;
        startinfo.RedirectStandardOutput = true;
        startinfo.RedirectStandardError  = true;
        startinfo.CreateNoWindow         = true;
        startinfo.Arguments              = command;

        if (!string.IsNullOrEmpty(workingDir) && Directory.Exists(workingDir))
        {
            startinfo.WorkingDirectory = workingDir;
        }

        /*
         * Process的StandardOutput和WaitForExit的使用不当,有可能导致死锁,参考如下:
         * https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput?redirectedfrom=MSDN&view=netframework-4.8#System_Diagnostics_Process_StandardOutput
         */
        var startTime = DateTime.Now;

        using (var process = System.Diagnostics.Process.Start(startinfo))
        {
            var output = new ProcessOutput();
            process.OutputDataReceived += output.OutputDataReceived;
            process.ErrorDataReceived  += output.OutputDataReceived;
            process.BeginOutputReadLine();

            if (timeoutMiliSeconds > 0)
            {
                process.WaitForExit(timeoutMiliSeconds);
            }
            else
            {
                process.WaitForExit();
            }
            //force process to exit when timeout
            if (!process.HasExited)
            {
                process.Kill();
                process.WaitForExit();
            }

            process.CancelOutputRead();
            output.OnExit(process.ExitCode, (process.ExitTime - startTime).TotalSeconds);
            return(output);
        }
    }