Beispiel #1
0
 /// <summary>
 /// Create a <see cref="IProcess"/> given an existing <paramref name="handle"/>.
 /// </summary>
 /// <param name="handle">The <see cref="global::System.Diagnostics.Process"/> to create a <see cref="IProcess"/> from.</param>
 /// <returns>The <see cref="IProcess"/> based on <paramref name="handle"/>.</returns>
 private IProcess CreateFromExistingHandle(global::System.Diagnostics.Process handle)
 {
     try
     {
         var pid = handle.Id;
         return(new Process(
                    processFeatures,
                    handle,
                    AttachExitHandler(handle, () => pid),
                    null,
                    null,
                    null,
                    loggerFactory.CreateLogger <Process>(),
                    true));
     }
     catch
     {
         handle.Dispose();
         throw;
     }
 }
Beispiel #2
0
        /// <inheritdoc />
        public IProcess LaunchProcess(string fileName, string workingDirectory, string arguments, bool readOutput, bool readError, bool noShellExecute)
        {
            logger.LogDebug("Launching process in {0}: {1} {2}", workingDirectory, fileName, arguments);
            var handle = new global::System.Diagnostics.Process();

            try
            {
                handle.StartInfo.FileName         = fileName;
                handle.StartInfo.Arguments        = arguments;
                handle.StartInfo.WorkingDirectory = workingDirectory;

                handle.StartInfo.UseShellExecute = !(noShellExecute || readOutput || readError);

                StringBuilder outputStringBuilder = null, errorStringBuilder = null, combinedStringBuilder = null;
                if (readOutput || readError)
                {
                    combinedStringBuilder = new StringBuilder();
                    if (readOutput)
                    {
                        outputStringBuilder = new StringBuilder();
                        handle.StartInfo.RedirectStandardOutput = true;
                        handle.OutputDataReceived += (sender, e) =>
                        {
                            combinedStringBuilder.Append(Environment.NewLine);
                            combinedStringBuilder.Append(e.Data);
                            outputStringBuilder.Append(Environment.NewLine);
                            outputStringBuilder.Append(e.Data);
                        };
                    }

                    if (readError)
                    {
                        errorStringBuilder = new StringBuilder();
                        handle.StartInfo.RedirectStandardError = true;
                        handle.ErrorDataReceived += (sender, e) =>
                        {
                            combinedStringBuilder.Append(Environment.NewLine);
                            combinedStringBuilder.Append(e.Data);
                            errorStringBuilder.Append(Environment.NewLine);
                            errorStringBuilder.Append(e.Data);
                        };
                    }
                }

                var lifetimeTask = AttachExitHandler(handle);

                handle.Start();
                try
                {
                    if (readOutput)
                    {
                        handle.BeginOutputReadLine();
                    }
                }
                catch (InvalidOperationException) { }
                try
                {
                    if (readError)
                    {
                        handle.BeginErrorReadLine();
                    }
                }
                catch (InvalidOperationException) { }

                return(new Process(handle, lifetimeTask, outputStringBuilder, errorStringBuilder, combinedStringBuilder, loggerFactory.CreateLogger <Process>(), false));
            }
            catch
            {
                handle.Dispose();
                throw;
            }
        }
Beispiel #3
0
        /// <inheritdoc />
        public IProcess LaunchProcess(
            string fileName,
            string workingDirectory,
            string arguments,
            bool readOutput,
            bool readError,
            bool noShellExecute)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(fileName));
            }
            if (workingDirectory == null)
            {
                throw new ArgumentNullException(nameof(workingDirectory));
            }
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            if (!noShellExecute && (readOutput || readError))
            {
                throw new InvalidOperationException("Requesting output/error reading requires noShellExecute to be true!");
            }

            logger.LogDebug(
                "{0}aunching process in {1}: {2} {3}",
                noShellExecute ? "L" : "Shell l",
                workingDirectory,
                fileName,
                arguments);
            var handle = new global::System.Diagnostics.Process();

            try
            {
                handle.StartInfo.FileName         = fileName;
                handle.StartInfo.Arguments        = arguments;
                handle.StartInfo.WorkingDirectory = workingDirectory;

                handle.StartInfo.UseShellExecute = !noShellExecute;

                StringBuilder combinedStringBuilder = null;

                Task <string> outputTask      = null;
                Task <string> errorTask       = null;
                var           processStartTcs = new TaskCompletionSource <object>();
                if (readOutput || readError)
                {
                    combinedStringBuilder = new StringBuilder();

                    async Task <string> ConsumeReader(Func <TextReader> readerFunc)
                    {
                        var    stringBuilder = new StringBuilder();
                        string text;

                        await processStartTcs.Task.ConfigureAwait(false);

                        var reader = readerFunc();

                        while ((text = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
                        {
                            combinedStringBuilder.AppendLine();
                            combinedStringBuilder.Append(text);
                            stringBuilder.AppendLine();
                            stringBuilder.Append(text);
                        }

                        return(stringBuilder.ToString());
                    }

                    if (readOutput)
                    {
                        outputTask = ConsumeReader(() => handle.StandardOutput);
                        handle.StartInfo.RedirectStandardOutput = true;
                    }

                    if (readError)
                    {
                        errorTask = ConsumeReader(() => handle.StandardError);
                        handle.StartInfo.RedirectStandardError = true;
                    }
                }

                var lifetimeTaskTask = AttachExitHandlerBeforeLaunch(handle, processStartTcs.Task);

                try
                {
                    handle.Start();

                    processStartTcs.SetResult(null);
                }
                catch (Exception ex)
                {
                    processStartTcs.SetException(ex);
                    throw;
                }

                var process = new Process(
                    processFeatures,
                    handle,
                    lifetimeTaskTask.GetAwaiter().GetResult(),                     // won't block
                    outputTask,
                    errorTask,
                    combinedStringBuilder,
                    loggerFactory.CreateLogger <Process>(), false);

                return(process);
            }
            catch
            {
                handle.Dispose();
                throw;
            }
        }