#region Copyright 2010-2014 by Roger Knapp, Licensed under the Apache License, Version 2.0
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.IO;
using CSharpTest.Net.IO;
using CSharpTest.Net.Utils;
namespace CSharpTest.Net.Processes
{
///
/// Defines a way to run scripts as an external process and capture their output.
///
public class ScriptRunner : IRunner, IDisposable
{
private readonly ProcessRunner _runner;
private readonly ScriptEngine _engine;
private readonly TempFile _scriptFile;
private readonly string[] _arguments;
///
/// Creates a runnable script with the specified language
///
public ScriptRunner(ScriptEngine.Language language, string script)
: this(ScriptEngine.GetDefaults(language), script)
{ }
///
/// Creates a runnable script with the specified engine parameters
///
public ScriptRunner(ScriptEngine engine, string script)
{
_engine = engine;
_scriptFile = _engine.Compile(script);
_arguments = ArgumentList.Parse(engine.ArgumentFormat.Replace("{SCRIPT}", _scriptFile.TempPath));
_runner = new ProcessRunner(engine.Executable, _arguments);
}
/// Return teh script engine being used
public ScriptEngine ScriptEngine { get { return _engine; } }
/// Return teh arguments to pass to script engine exe
public string[] ScriptArguments { get { return _arguments; } }
/// Returns the temp file of the script
public string ScriptFile { get { return _scriptFile.TempPath; } }
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
public void Dispose()
{
_scriptFile.Dispose();
}
///
/// Returns a that represents the current .
///
public override string ToString()
{
return _runner.ToString();
}
/// Notifies caller of writes to the std::err or std::out
public event ProcessOutputEventHandler OutputReceived
{
add { _runner.OutputReceived += value; }
remove { _runner.OutputReceived -= value; }
}
/// Notifies caller when the process exits
public event ProcessExitedEventHandler ProcessExited
{
add { _runner.ProcessExited += value; }
remove { _runner.ProcessExited -= value; }
}
/// Allows writes to the std::in for the process
public System.IO.TextWriter StandardInput { get { return _runner.StandardInput; } }
/// Waits for the process to exit and returns the exit code
public int ExitCode
{
get { return _runner.ExitCode; }
}
/// Gets or sets the initial working directory for the process.
public string WorkingDirectory { get { return _runner.WorkingDirectory; } set { _runner.WorkingDirectory = value; } }
/// Returns true if this instance is running a process
public bool IsRunning
{
get { return _runner.IsRunning; }
}
/// Kills the process if it is still running
public void Kill() { _runner.Kill(); }
/// Closes std::in and waits for the process to exit
public void WaitForExit() { _runner.WaitForExit(); }
/// Closes std::in and waits for the process to exit, returns false if the process did not exit in the time given
public bool WaitForExit(TimeSpan timeout)
{ return _runner.WaitForExit(timeout); }
/// Runs the process and returns the exit code.
public int Run() { return Run(new string[0]); }
/// Runs the process and returns the exit code.
public int Run(params string[] args) { return Run(null, args); }
/// Runs the process and returns the exit code.
public int Run(TextReader input, params string[] arguments)
{
if (input == null && _engine.UsesStandardInputScript)
input = new StringReader(_scriptFile.ReadAllText());
return _runner.Run(input, arguments);
}
/// Runs the process and returns the exit code.
public void Start() { Start(new string[0]); }
/// Starts the process and returns.
public void Start(params string[] args)
{
_runner.Start(args);
if (_engine.UsesStandardInputScript)
{
_runner.StandardInput.Write(_scriptFile.ReadAllText());
_runner.StandardInput.Close();
}
}
}
}