Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1092 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
33 changed files with 90 additions and 535 deletions
@ -1,98 +0,0 @@
@@ -1,98 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Text; |
||||
using System.Threading; |
||||
|
||||
namespace ICSharpCode.CodeCoverage |
||||
{ |
||||
/// <summary>
|
||||
/// A threaded <see cref="Process.StandardOutput"/> or
|
||||
/// <see cref="Process.StandardError"/> reader.
|
||||
/// </summary>
|
||||
public class OutputReader |
||||
{ |
||||
StreamReader reader; |
||||
string output = String.Empty; |
||||
Thread thread; |
||||
|
||||
public event LineReceivedEventHandler LineReceived; |
||||
|
||||
public OutputReader(StreamReader reader) |
||||
{ |
||||
this.reader = reader; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Starts reading the output stream.
|
||||
/// </summary>
|
||||
public void Start() |
||||
{ |
||||
thread = new Thread(new ThreadStart(ReadOutput)); |
||||
thread.Start(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the text output read from the reader.
|
||||
/// </summary>
|
||||
public string Output { |
||||
get { |
||||
return output; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Waits for the reader to finish.
|
||||
/// </summary>
|
||||
public void WaitForFinish() |
||||
{ |
||||
if (thread != null) { |
||||
thread.Join(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="LineReceived"/> event.
|
||||
/// </summary>
|
||||
/// <param name="line"></param>
|
||||
protected void OnLineReceived(string line) |
||||
{ |
||||
if (LineReceived != null) { |
||||
LineReceived(this, new LineReceivedEventArgs(line)); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Reads the output stream on a different thread.
|
||||
/// </summary>
|
||||
void ReadOutput() |
||||
{ |
||||
//output = reader.ReadToEnd();
|
||||
output = String.Empty; |
||||
StringBuilder outputBuilder = new StringBuilder(); |
||||
|
||||
bool endOfStream = false; |
||||
while(!endOfStream) |
||||
{ |
||||
string line = reader.ReadLine(); |
||||
|
||||
if (line != null) { |
||||
outputBuilder.Append(line); |
||||
outputBuilder.Append(Environment.NewLine); |
||||
OnLineReceived(line); |
||||
} else { |
||||
endOfStream = true; |
||||
} |
||||
} |
||||
|
||||
output = outputBuilder.ToString(); |
||||
} |
||||
} |
||||
} |
@ -1,266 +0,0 @@
@@ -1,266 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using ICSharpCode.Core; |
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace ICSharpCode.CodeCoverage |
||||
{ |
||||
/// <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>
|
||||
/// Triggered when a line of text is read from the standard error.
|
||||
/// </summary>
|
||||
public event LineReceivedEventHandler ErrorLineReceived; |
||||
|
||||
/// <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(StringParser.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>
|
||||
/// Starts 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 Start(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); |
||||
if (ErrorLineReceived != null) { |
||||
standardErrorReader.LineReceived += new LineReceivedEventHandler(OnErrorLineReceived); |
||||
} |
||||
|
||||
standardErrorReader.Start(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Starts the process.
|
||||
/// </summary>
|
||||
/// <param name="command">The process filename.</param>
|
||||
public void Start(string command) |
||||
{ |
||||
Start(command, String.Empty); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Kills the running process.
|
||||
/// </summary>
|
||||
public void Kill() |
||||
{ |
||||
if (process != null) { |
||||
if (!process.HasExited) { |
||||
process.Kill(); |
||||
process.Close(); |
||||
process.Dispose(); |
||||
process = null; |
||||
standardOutputReader.WaitForFinish(); |
||||
standardErrorReader.WaitForFinish(); |
||||
} else { |
||||
process = null; |
||||
} |
||||
} |
||||
// 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); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="ErrorLineReceived"/> event.
|
||||
/// </summary>
|
||||
/// <param name="sender">The event source.</param>
|
||||
/// <param name="e">The line received event arguments.</param>
|
||||
protected void OnErrorLineReceived(object sender, LineReceivedEventArgs e) |
||||
{ |
||||
if (ErrorLineReceived != null) { |
||||
ErrorLineReceived(this, e); |
||||
} |
||||
} |
||||
|
||||
enum ConsoleEvent |
||||
{ |
||||
ControlC = 0, |
||||
ControlBreak = 1 |
||||
}; |
||||
|
||||
[DllImport("kernel32.dll", SetLastError=true)] |
||||
static extern int GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId); |
||||
} |
||||
} |
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.CodeCoverage |
||||
{ |
||||
/// <summary>
|
||||
/// An exception thrown by a <see cref="ProcessRunner"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
public class ProcessRunnerException : ApplicationException |
||||
{ |
||||
public ProcessRunnerException(string message) |
||||
: base(message) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.NAntAddIn |
||||
{ |
||||
public delegate void LineReceivedEventHandler(object sender, LineReceivedEventArgs e); |
||||
|
||||
/// <summary>
|
||||
/// The arguments for the <see cref="LineReceivedEventHandler"/> event.
|
||||
/// </summary>
|
||||
public class LineReceivedEventArgs : EventArgs |
||||
{ |
||||
string line = String.Empty; |
||||
|
||||
public LineReceivedEventArgs(string line) |
||||
{ |
||||
this.line = line; |
||||
} |
||||
|
||||
public string Line { |
||||
get { |
||||
return line; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Configuration; |
||||
|
||||
namespace ICSharpCode.NAntAddIn.Tests |
||||
{ |
||||
/// <summary>
|
||||
/// Description of Config.
|
||||
/// </summary>
|
||||
public class Config |
||||
{ |
||||
private Config() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the console app exe we are going to use to test the
|
||||
/// ProcessRunner.
|
||||
/// </summary>
|
||||
public static string ConsoleAppFilename { |
||||
get { |
||||
return typeof(ICSharpCode.NAntAddIn.Tests.ConsoleApp.ConsoleApp).Assembly.Location; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?> |
||||
<configuration> |
||||
<appSettings> |
||||
<!-- |
||||
<add key="consoleApp" value="C:\Projects\dotnet\Corsavy\SharpDevelop\src\AddIns\Misc\NAntAddIn\ConsoleApp\bin\ConsoleApp.exe" /> |
||||
--> |
||||
</appSettings> |
||||
</configuration> |
||||
|
Binary file not shown.
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Tests |
||||
{ |
||||
public class ConsoleAppTestFixtureBase |
||||
{ |
||||
public static string GetConsoleAppFileName() |
||||
{ |
||||
return typeof(ICSharpCode.NAntAddIn.Tests.ConsoleApp.ConsoleApp).Assembly.Location; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue