⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processrunner.cs

📁 c#源代码
💻 CS
字号:
//
// SharpDevelop NAnt add-in.
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ICSharpCode.NAntAddIn
{
	/// <summary>
	/// Runs a process that sends output to standard output and to
	/// standard error.
	/// </summary>
	public class ProcessRunner : IDisposable
	{
		Process process;
		string standardOutput = String.Empty;
		string workingDirectory = String.Empty;
		OutputReader standardOutputReader;
		OutputReader standardErrorReader;

		/// <summary>
		/// Triggered when the process has exited.
		/// </summary>
		public event EventHandler ProcessExited;
		
		/// <summary>
		/// Triggered when a line of text is read from the standard output.
		/// </summary>
		public event LineReceivedEventHandler OutputLineReceived;
		
		/// <summary>
		/// Creates a new instance of the <see cref="ProcessRunner"/>.
		/// </summary>
		public ProcessRunner()
		{
		}
		
		/// <summary>
		/// Gets or sets the process's working directory.
		/// </summary>
		public string WorkingDirectory {
			get {
				return workingDirectory;
			}
			
			set {
				workingDirectory = value;
			}
		}

		/// <summary>
		/// Gets the standard output returned from the process.
		/// </summary>
		public string StandardOutput {
			get {
				string output = String.Empty;
				if (standardOutputReader != null) {
					output = standardOutputReader.Output;
				}
				return output;
			}
		}
		
		/// <summary>
		/// Gets the standard error output returned from the process.
		/// </summary>
		public string StandardError {
			get {
				string output = String.Empty;
				if (standardErrorReader != null) {
					output = standardErrorReader.Output;
				}
				return output;
			}
		}
		
		/// <summary>
		/// Releases resources held by the <see cref="ProcessRunner"/>
		/// </summary>
		public void Dispose()
		{
		}
		
		/// <summary>
		/// Gets the process exit code.
		/// </summary>
		public int ExitCode {
			get {	
				int exitCode = 0;
				if (process != null) {
					exitCode = process.ExitCode;
				}
				return exitCode;
			}
		}
		
		/// <summary>
		/// Waits for the process to exit.
		/// </summary>
		public void WaitForExit()
		{
			WaitForExit(Int32.MaxValue);
		}
		
		/// <summary>
		/// Waits for the process to exit.
		/// </summary>
		/// <param name="timeout">A timeout in milliseconds.</param>
		/// <returns><see langword="true"/> if the associated process has 
		/// exited; otherwise, <see langword="false"/></returns>
		public bool WaitForExit(int timeout)
		{
			if (process == null) {
				throw new ProcessRunnerException(SharpDevelopApplication.StringParserService.Parse("${res:ICSharpCode.NAntAddIn.ProcessRunner.NoProcessRunningErrorText}"));
			}
			
			bool exited = process.WaitForExit(timeout);
			
			if (exited) {
				standardOutputReader.WaitForFinish();
				standardErrorReader.WaitForFinish();
			}
			
			return exited;
		}
		
		public bool IsRunning {
			get {
				bool isRunning = false;
				
				if (process != null) {
					isRunning = !process.HasExited;
				}
				
				return isRunning;
			}
		}
		
		/// <summary>
		/// Runs the process.
		/// </summary>
		/// <param name="command">The process filename.</param>
		/// <param name="arguments">The command line arguments to
		/// pass to the command.</param>
		public void Run(string command, string arguments)
		{	
			process = new Process();
			process.StartInfo.CreateNoWindow = true;
			process.StartInfo.FileName = command;
			process.StartInfo.WorkingDirectory = workingDirectory;
			process.StartInfo.RedirectStandardOutput = true;
			process.StartInfo.RedirectStandardError = true;
			process.StartInfo.UseShellExecute = false;
			process.StartInfo.Arguments = arguments;
			
			if (ProcessExited != null) {
				process.EnableRaisingEvents = true;
				process.Exited += new EventHandler(OnProcessExited);
			}

			process.Start();
			
			standardOutputReader = new OutputReader(process.StandardOutput);
			if (OutputLineReceived != null) {
				standardOutputReader.LineReceived += new LineReceivedEventHandler(OnOutputLineReceived);
			}
			
			standardOutputReader.Start();
			
			standardErrorReader = new OutputReader(process.StandardError);
			standardErrorReader.Start();
		}
		
		/// <summary>
		/// Runs the process.
		/// </summary>
		/// <param name="command">The process filename.</param>
		public void Run(string command)
		{
			Run(command, String.Empty);
		}
		
		/// <summary>
		/// Kills the running process.
		/// </summary>
		public void Kill()
		{
			if (process != null) {
				process.Kill();
				process.Close();
				process.Dispose();
				process = null;
				standardOutputReader.WaitForFinish();
				standardErrorReader.WaitForFinish();
			}
			// Control-C does not seem to work.
			//GenerateConsoleCtrlEvent((int)ConsoleEvent.ControlC, 0);
		}		
		
		/// <summary>
		/// Raises the <see cref="ProcessExited"/> event.
		/// </summary>
		protected void OnProcessExited(object sender, EventArgs e)
		{
			if (ProcessExited != null) {
				
				standardOutputReader.WaitForFinish();
				standardErrorReader.WaitForFinish();
				
				ProcessExited(this, e);
			}
		}
		
		/// <summary>
		/// Raises the <see cref="OutputLineReceived"/> event.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The line received event arguments.</param>
		protected void OnOutputLineReceived(object sender, LineReceivedEventArgs e)
		{
			if (OutputLineReceived != null) {
				OutputLineReceived(this, e);
			}
		}

		enum ConsoleEvent
		{
			ControlC = 0,
			ControlBreak = 1
		};
		
		[DllImport("kernel32.dll", SetLastError=true)] 
		static extern int GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -