Esempio n. 1
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);
                }
            }
Esempio n. 2
0
        public override void StartProcess(string command, string arguments, string workDir, Dictionary <string, string> envVariables)
        {
            ProcessOperation operation = CommandLog.LogProcessStart(command, arguments, workDir);

            try
            {
                var commandLine = new ArgumentBuilder {
                    command.Quote(), arguments
                }.ToString();
                ConsoleCommandLineOutputProcessor outputProcessor = new(commandLine.Length, FireDataReceived);

                ConEmuStartInfo startInfo = new()
                {
                    ConsoleProcessCommandLine        = commandLine,
                    IsEchoingConsoleCommandLine      = true,
                    WhenConsoleProcessExits          = WhenConsoleProcessExits.KeepConsoleEmulatorAndShowMessage,
                    AnsiStreamChunkReceivedEventSink = outputProcessor.AnsiStreamChunkReceived,
                    StartupDirectory = workDir
                };

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

                startInfo.ConsoleProcessExitedEventSink = (_, args) =>
                {
                    _nLastExitCode = args.ExitCode;
                    operation.LogProcessEnd(_nLastExitCode);
                    outputProcessor.Flush();
                    FireProcessExited();
                };

                startInfo.ConsoleEmulatorClosedEventSink = (sender, _) =>
                {
                    Validates.NotNull(_terminal);
                    if (sender == _terminal.RunningSession)
                    {
                        FireTerminated();
                    }
                };

                Validates.NotNull(_terminal);
                _terminal.Start(startInfo, ThreadHelper.JoinableTaskFactory, AppSettings.ConEmuStyle.Value, AppSettings.ConEmuConsoleFont.Name, AppSettings.ConEmuConsoleFont.Size.ToString(CultureInfo.InvariantCulture));
            }
            catch (Exception ex)
            {
                operation.LogProcessEnd(ex);
                throw;
            }
        }
Esempio n. 3
0
            private void OnProcessExit(object sender, EventArgs eventArgs)
            {
                // The Exited event can be raised after the process is disposed, however
                // if the Process is disposed then reading ExitCode will throw.
                if (_disposed == 0)
                {
                    ExitCode = _process.ExitCode;
                }

                _logOperation.LogProcessEnd(ExitCode);
                _exitTaskCompletionSource.TrySetResult(ExitCode);
            }
Esempio n. 4
0
 private void OnProcessExit(object sender, EventArgs eventArgs)
 {
     lock (_syncRoot)
     {
         // The Exited event can be raised after the process is disposed, however
         // if the Process is disposed then reading ExitCode will throw.
         if (!_disposed)
         {
             try
             {
                 var exitCode = _process.ExitCode;
                 _logOperation.LogProcessEnd(exitCode);
                 _exitTaskCompletionSource.TrySetResult(exitCode);
             }
             catch (Exception ex)
             {
                 _logOperation.LogProcessEnd(ex);
                 _exitTaskCompletionSource.TrySetException(ex);
             }
         }
     }
 }
Esempio n. 5
0
            public ProcessWrapper(string fileName,
                                  string arguments,
                                  string workDir,
                                  bool createWindow,
                                  bool redirectInput,
                                  bool redirectOutput,
                                  [CanBeNull] Encoding outputEncoding,
                                  bool useShellExecute)
            {
                Debug.Assert(redirectOutput == (outputEncoding != null), "redirectOutput == (outputEncoding != null)");
                _redirectInput  = redirectInput;
                _redirectOutput = redirectOutput;

                _process = new Process
                {
                    EnableRaisingEvents = true,
                    StartInfo           =
                    {
                        UseShellExecute        = useShellExecute,
                        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();
                    _logOperation.SetProcessId(_process.Id);
                }
                catch (Exception ex)
                {
                    Dispose();

                    _logOperation.LogProcessEnd(ex);
                    throw new ExternalOperationException(fileName, arguments, workDir, ex);
                }
            }
Esempio n. 6
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;
            }
        }