コード例 #1
0
ファイル: ProcessOutput.cs プロジェクト: RussBaz/PTVS
        private ProcessOutput(Process process, Redirector redirector) {
            _arguments = QuoteSingleArgument(process.StartInfo.FileName) + " " + process.StartInfo.Arguments;
            _redirector = redirector;
            if (_redirector == null) {
                _output = new List<string>();
                _error = new List<string>();
            }

            _process = process;
            if (_process.StartInfo.RedirectStandardOutput) {
                _process.OutputDataReceived += OnOutputDataReceived;
            }
            if (_process.StartInfo.RedirectStandardError) {
                _process.ErrorDataReceived += OnErrorDataReceived;
            }

            if (!_process.StartInfo.RedirectStandardOutput && !_process.StartInfo.RedirectStandardError) {
                // If we are receiving output events, we signal that the process
                // has exited when one of them receives null. Otherwise, we have
                // to listen for the Exited event.
                // If we just listen for the Exited event, we may receive it
                // before all the output has arrived.
                _process.Exited += OnExited;
            }
            _process.EnableRaisingEvents = true;

            try {
                _process.Start();
            } catch (Exception ex) {
                if (IsCriticalException(ex)) {
                    throw;
                }
                if (_redirector != null) {
                    foreach (var line in SplitLines(ex.ToString())) {
                        _redirector.WriteErrorLine(line);
                    }
                } else if (_error != null) {
                    _error.AddRange(SplitLines(ex.ToString()));
                }
                _process = null;
            }

            if (_process != null) {
                if (_process.StartInfo.RedirectStandardOutput) {
                    _process.BeginOutputReadLine();
                }
                if (_process.StartInfo.RedirectStandardError) {
                    _process.BeginErrorReadLine();
                }
                
                if (_process.StartInfo.RedirectStandardInput) {
                    // Close standard input so that we don't get stuck trying to read input from the user.
                    try {
                        _process.StandardInput.Close();
                    } catch (InvalidOperationException) {
                        // StandardInput not available
                    }
                }
            }
        }
コード例 #2
0
ファイル: ProcessOutput.cs プロジェクト: RussBaz/PTVS
        /// <summary>
        /// Runs the file with the provided settings as a user with
        /// administrative permissions. The window is always hidden and output
        /// is provided to the redirector when the process terminates.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs"></param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput RunElevated(
            string filename,
            IEnumerable<string> arguments,
            string workingDirectory,
            Redirector redirector,
            bool quoteArgs = true,
            Encoding outputEncoding = null,
            Encoding errorEncoding = null
        ) {
            var outFile = Path.GetTempFileName();
            var errFile = Path.GetTempFileName();
            var psi = new ProcessStartInfo("cmd.exe");
            psi.CreateNoWindow = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb = "runas";

            string args;
            if (quoteArgs) {
                args = string.Join(" ", arguments.Where(a => a != null).Select(QuoteSingleArgument));
            } else {
                args = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.Arguments = string.Format("/S /C \"{0} {1} >>{2} 2>>{3}\"",
                QuoteSingleArgument(filename),
                args,
                QuoteSingleArgument(outFile),
                QuoteSingleArgument(errFile)
            );
            psi.WorkingDirectory = workingDirectory;
            psi.CreateNoWindow = true;
            psi.UseShellExecute = true;

            var process = new Process();
            process.StartInfo = psi;
            var result = new ProcessOutput(process, redirector);
            if (redirector != null) {
                result.Exited += (s, e) => {
                    try {
                        try {
                            var lines = File.ReadAllLines(outFile, outputEncoding ?? Encoding.Default);
                            foreach (var line in lines) {
                                redirector.WriteLine(line);
                            }
                        } catch (Exception ex) {
                            if (IsCriticalException(ex)) {
                                throw;
                            }
                            redirector.WriteErrorLine("Failed to obtain standard output from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString())) {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard output from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                        try {
                            var lines = File.ReadAllLines(errFile, errorEncoding ?? outputEncoding ?? Encoding.Default);
                            foreach (var line in lines) {
                                redirector.WriteErrorLine(line);
                            }
                        } catch (Exception ex) {
                            if (IsCriticalException(ex)) {
                                throw;
                            }
                            redirector.WriteErrorLine("Failed to obtain standard error from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString())) {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard error from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                    } finally {
                        try {
                            File.Delete(outFile);
                        } catch { }
                        try {
                            File.Delete(errFile);
                        } catch { }
                    }
                };
            }
            return result;
        }
コード例 #3
0
ファイル: ProcessOutput.cs プロジェクト: RussBaz/PTVS
        /// <summary>
        /// Runs the file with the provided settings.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="env">Environment variables to set.</param>
        /// <param name="visible">
        /// False to hide the window and redirect output to
        /// <see cref="StandardOutputLines"/> and
        /// <see cref="StandardErrorLines"/>.
        /// </param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs">
        /// True to ensure each argument is correctly quoted.
        /// </param>
        /// <param name="elevate">
        /// True to run the process as an administrator. See
        /// <see cref="RunElevated"/>.
        /// </param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput Run(
            string filename,
            IEnumerable<string> arguments,
            string workingDirectory,
            IEnumerable<KeyValuePair<string, string>> env,
            bool visible,
            Redirector redirector,
            bool quoteArgs = true,
            bool elevate = false,
            Encoding outputEncoding = null,
            Encoding errorEncoding = null
        ) {
            if (string.IsNullOrEmpty(filename)) {
                throw new ArgumentException("Filename required", "filename");
            }
            if (elevate) {
                return RunElevated(
                    filename,
                    arguments,
                    workingDirectory,
                    redirector,
                    quoteArgs,
                    outputEncoding,
                    errorEncoding
                );
            }

            var psi = new ProcessStartInfo(filename);
            if (quoteArgs) {
                psi.Arguments = string.Join(" ",
                    arguments.Where(a => a != null).Select(QuoteSingleArgument));
            } else {
                psi.Arguments = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.WorkingDirectory = workingDirectory;
            psi.CreateNoWindow = !visible;
            psi.UseShellExecute = false;
            psi.RedirectStandardError = !visible || (redirector != null);
            psi.RedirectStandardOutput = !visible || (redirector != null);
            psi.RedirectStandardInput = !visible;
            psi.StandardOutputEncoding = outputEncoding ?? psi.StandardOutputEncoding;
            psi.StandardErrorEncoding = errorEncoding ?? outputEncoding ?? psi.StandardErrorEncoding;
            if (env != null) {
                foreach (var kv in env) {
                    psi.EnvironmentVariables[kv.Key] = kv.Value;
                }
            }

            var process = new Process { StartInfo = psi };
            return new ProcessOutput(process, redirector);
        }
コード例 #4
0
ファイル: ProcessOutput.cs プロジェクト: yepeiwen/PTVS
        private ProcessOutput(Process process, Redirector redirector)
        {
            _arguments  = QuoteSingleArgument(process.StartInfo.FileName) + " " + process.StartInfo.Arguments;
            _redirector = redirector;
            if (_redirector == null)
            {
                _output = new List <string>();
                _error  = new List <string>();
            }

            _process = process;
            if (_process.StartInfo.RedirectStandardOutput)
            {
                _process.OutputDataReceived += OnOutputDataReceived;
            }
            if (_process.StartInfo.RedirectStandardError)
            {
                _process.ErrorDataReceived += OnErrorDataReceived;
            }

            if (!_process.StartInfo.RedirectStandardOutput && !_process.StartInfo.RedirectStandardError)
            {
                // If we are receiving output events, we signal that the process
                // has exited when one of them receives null. Otherwise, we have
                // to listen for the Exited event.
                // If we just listen for the Exited event, we may receive it
                // before all the output has arrived.
                _process.Exited += OnExited;
            }
            _process.EnableRaisingEvents = true;

            try {
                _process.Start();
            } catch (Exception ex) {
                if (IsCriticalException(ex))
                {
                    throw;
                }
                if (_redirector != null)
                {
                    foreach (var line in SplitLines(ex.ToString()))
                    {
                        _redirector.WriteErrorLine(line);
                    }
                }
                else if (_error != null)
                {
                    _error.AddRange(SplitLines(ex.ToString()));
                }
                _process = null;
            }

            if (_process != null)
            {
                if (_process.StartInfo.RedirectStandardOutput)
                {
                    _process.BeginOutputReadLine();
                }
                if (_process.StartInfo.RedirectStandardError)
                {
                    _process.BeginErrorReadLine();
                }

                if (_process.StartInfo.RedirectStandardInput)
                {
                    // Close standard input so that we don't get stuck trying to read input from the user.
                    try {
                        _process.StandardInput.Close();
                    } catch (InvalidOperationException) {
                        // StandardInput not available
                    }
                }
            }
        }
コード例 #5
0
ファイル: ProcessOutput.cs プロジェクト: yepeiwen/PTVS
        /// <summary>
        /// Runs the file with the provided settings as a user with
        /// administrative permissions. The window is always hidden and output
        /// is provided to the redirector when the process terminates.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs"></param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput RunElevated(
            string filename,
            IEnumerable <string> arguments,
            string workingDirectory,
            Redirector redirector,
            bool quoteArgs          = true,
            Encoding outputEncoding = null,
            Encoding errorEncoding  = null
            )
        {
            var outFile = Path.GetTempFileName();
            var errFile = Path.GetTempFileName();
            var psi     = new ProcessStartInfo("cmd.exe");

            psi.CreateNoWindow  = true;
            psi.WindowStyle     = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb            = "runas";

            string args;

            if (quoteArgs)
            {
                args = string.Join(" ", arguments.Where(a => a != null).Select(QuoteSingleArgument));
            }
            else
            {
                args = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.Arguments = string.Format("/S /C \"{0} {1} >>{2} 2>>{3}\"",
                                          QuoteSingleArgument(filename),
                                          args,
                                          QuoteSingleArgument(outFile),
                                          QuoteSingleArgument(errFile)
                                          );
            psi.WorkingDirectory = workingDirectory;
            psi.CreateNoWindow   = true;
            psi.UseShellExecute  = true;

            var process = new Process();

            process.StartInfo = psi;
            var result = new ProcessOutput(process, redirector);

            if (redirector != null)
            {
                result.Exited += (s, e) => {
                    try {
                        try {
                            var lines = File.ReadAllLines(outFile, outputEncoding ?? Encoding.Default);
                            foreach (var line in lines)
                            {
                                redirector.WriteLine(line);
                            }
                        } catch (Exception ex) {
                            if (IsCriticalException(ex))
                            {
                                throw;
                            }
                            redirector.WriteErrorLine("Failed to obtain standard output from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString()))
                            {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard output from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                        try {
                            var lines = File.ReadAllLines(errFile, errorEncoding ?? outputEncoding ?? Encoding.Default);
                            foreach (var line in lines)
                            {
                                redirector.WriteErrorLine(line);
                            }
                        } catch (Exception ex) {
                            if (IsCriticalException(ex))
                            {
                                throw;
                            }
                            redirector.WriteErrorLine("Failed to obtain standard error from elevated process.");
#if DEBUG
                            foreach (var line in SplitLines(ex.ToString()))
                            {
                                redirector.WriteErrorLine(line);
                            }
#else
                            Trace.TraceError("Failed to obtain standard error from elevated process.");
                            Trace.TraceError(ex.ToString());
#endif
                        }
                    } finally {
                        try {
                            File.Delete(outFile);
                        } catch { }
                        try {
                            File.Delete(errFile);
                        } catch { }
                    }
                };
            }
            return(result);
        }
コード例 #6
0
ファイル: ProcessOutput.cs プロジェクト: yepeiwen/PTVS
        /// <summary>
        /// Runs the file with the provided settings.
        /// </summary>
        /// <param name="filename">Executable file to run.</param>
        /// <param name="arguments">Arguments to pass.</param>
        /// <param name="workingDirectory">Starting directory.</param>
        /// <param name="env">Environment variables to set.</param>
        /// <param name="visible">
        /// False to hide the window and redirect output to
        /// <see cref="StandardOutputLines"/> and
        /// <see cref="StandardErrorLines"/>.
        /// </param>
        /// <param name="redirector">
        /// An object to receive redirected output.
        /// </param>
        /// <param name="quoteArgs">
        /// True to ensure each argument is correctly quoted.
        /// </param>
        /// <param name="elevate">
        /// True to run the process as an administrator. See
        /// <see cref="RunElevated"/>.
        /// </param>
        /// <returns>A <see cref="ProcessOutput"/> object.</returns>
        public static ProcessOutput Run(
            string filename,
            IEnumerable <string> arguments,
            string workingDirectory,
            IEnumerable <KeyValuePair <string, string> > env,
            bool visible,
            Redirector redirector,
            bool quoteArgs          = true,
            bool elevate            = false,
            Encoding outputEncoding = null,
            Encoding errorEncoding  = null
            )
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentException("Filename required", "filename");
            }
            if (elevate)
            {
                return(RunElevated(
                           filename,
                           arguments,
                           workingDirectory,
                           redirector,
                           quoteArgs,
                           outputEncoding,
                           errorEncoding
                           ));
            }

            var psi = new ProcessStartInfo(filename);

            if (quoteArgs)
            {
                psi.Arguments = string.Join(" ",
                                            arguments.Where(a => a != null).Select(QuoteSingleArgument));
            }
            else
            {
                psi.Arguments = string.Join(" ", arguments.Where(a => a != null));
            }
            psi.WorkingDirectory       = workingDirectory;
            psi.CreateNoWindow         = !visible;
            psi.UseShellExecute        = false;
            psi.RedirectStandardError  = !visible || (redirector != null);
            psi.RedirectStandardOutput = !visible || (redirector != null);
            psi.RedirectStandardInput  = !visible;
            psi.StandardOutputEncoding = outputEncoding ?? psi.StandardOutputEncoding;
            psi.StandardErrorEncoding  = errorEncoding ?? outputEncoding ?? psi.StandardErrorEncoding;
            if (env != null)
            {
                foreach (var kv in env)
                {
                    psi.EnvironmentVariables[kv.Key] = kv.Value;
                }
            }

            var process = new Process {
                StartInfo = psi
            };

            return(new ProcessOutput(process, redirector));
        }