#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(); } } } }