Пример #1
0
            public ProcessWrapper(string fileName, string arguments, string workDir, bool createWindow, bool redirectInput, bool redirectOutput, [CanBeNull] Encoding outputEncoding)
            {
                Debug.Assert(redirectOutput == (outputEncoding != null), "redirectOutput == (outputEncoding != null)");
                _redirectInput  = redirectInput;
                _redirectOutput = redirectOutput;

                _process = new Process
                {
                    EnableRaisingEvents = true,
                    StartInfo           =
                    {
                        UseShellExecute        = false,
                        ErrorDialog            = false,
                        CreateNoWindow         = !createWindow,
                        RedirectStandardInput  = redirectInput,
                        RedirectStandardOutput = redirectOutput,
                        RedirectStandardError  = redirectOutput,
                        StandardOutputEncoding = outputEncoding,
                        StandardErrorEncoding  = outputEncoding,
                        FileName         = fileName,
                        Arguments        = arguments,
                        WorkingDirectory = workDir
                    }
                };

                _logOperation = CommandLog.LogProcessStart(fileName, arguments, workDir);

                _process.Exited += OnProcessExit;

                _process.Start();

                _logOperation.SetProcessId(_process.Id);
            }
Пример #2
0
            public ProcessWrapper(string fileName,
                                  string arguments,
                                  string workDir,
                                  bool createWindow,
                                  bool redirectInput,
                                  bool redirectOutput,
                                  Encoding?outputEncoding,
                                  bool useShellExecute)
            {
                Debug.Assert(redirectOutput == (outputEncoding is not null), "redirectOutput == (outputEncoding is not null)");
                _redirectInput  = redirectInput;
                _redirectOutput = redirectOutput;

                _process = new Process
                {
                    EnableRaisingEvents = true,
                    StartInfo           =
                    {
                        UseShellExecute        = useShellExecute,
                        Verb                   = useShellExecute ? "open" : string.Empty,
                        ErrorDialog            = false,
                        CreateNoWindow         = !createWindow,
                        RedirectStandardInput  = redirectInput,
                        RedirectStandardOutput = redirectOutput,
                        RedirectStandardError  = redirectOutput,
                        StandardOutputEncoding = outputEncoding,
                        StandardErrorEncoding  = outputEncoding,
                        FileName               = fileName,
                        Arguments              = arguments,
                        WorkingDirectory       = workDir
                    }
                };

                _logOperation = CommandLog.LogProcessStart(fileName, arguments, workDir);

                _process.Exited += OnProcessExit;

                try
                {
                    _process.Start();
                    try
                    {
                        _logOperation.SetProcessId(_process.Id);
                    }
                    catch (InvalidOperationException ex) when(useShellExecute)
                    {
                        // _process.Start() has succeeded, ignore the failure getting the _process.Id
                        _logOperation.LogProcessEnd(ex);
                    }
                }
                catch (Exception ex)
                {
                    Dispose();

                    _logOperation.LogProcessEnd(ex);
                    throw new ExternalOperationException(fileName, arguments, workDir, ex);
                }
            }
Пример #3
0
        public override void StartProcess(string command, string arguments, string workDir, Dictionary <string, string> envVariables)
        {
            ProcessOperation operation = CommandLog.LogProcessStart(command, arguments, workDir);

            try
            {
                EnvironmentConfiguration.SetEnvironmentVariables();

                bool ssh = GitSshHelpers.UseSsh(arguments);

                KillProcess();

                // process used to execute external commands
                var outputEncoding = GitModule.SystemEncoding;
                var startInfo      = new ProcessStartInfo
                {
                    UseShellExecute        = false,
                    ErrorDialog            = false,
                    CreateNoWindow         = !ssh && !AppSettings.ShowGitCommandLine,
                    RedirectStandardInput  = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    StandardOutputEncoding = outputEncoding,
                    StandardErrorEncoding  = outputEncoding,
                    FileName         = command,
                    Arguments        = arguments,
                    WorkingDirectory = workDir
                };

                foreach (var(name, value) in envVariables)
                {
                    startInfo.EnvironmentVariables.Add(name, value);
                }

                var process = new Process {
                    StartInfo = startInfo, EnableRaisingEvents = true
                };

                process.OutputDataReceived += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.ErrorDataReceived  += (sender, args) => FireDataReceived(new TextEventArgs((args.Data ?? "") + '\n'));
                process.Exited             += delegate
                {
                    this.InvokeAsync(
                        () =>
                    {
                        if (_process is null)
                        {
                            operation.LogProcessEnd(new Exception("Process instance is null in Exited event"));
                            return;
                        }

                        // The process is exited already, but this command waits also until all output is received.
                        // Only WaitForExit when someone is connected to the exited event. For some reason a
                        // null reference is thrown sometimes when staging/unstaging in the commit dialog when
                        // we wait for exit, probably a timing issue...
                        try
                        {
                            _process.WaitForExit();
                        }
                        catch (Exception ex)
                        {
                            operation.LogProcessEnd(ex);
                        }

                        _exitcode = _process.ExitCode;
                        operation.LogProcessEnd(_exitcode);
                        _process = null;
                        _outputThrottle?.FlushOutput();
                        FireProcessExited();
                        _outputThrottle?.Stop(flush: true);
                    }).FileAndForget();
                };

                process.Start();
                operation.SetProcessId(process.Id);
                _process = process;
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
            }
            catch (Exception ex)
            {
                operation.LogProcessEnd(ex);
                ex.Data.Add("command", command);
                ex.Data.Add("arguments", arguments);
                throw;
            }
        }