using System; using System.Diagnostics; using System.IO; using ln.logging; namespace ln.build { public enum CRThrow { NEVER, NEGATIVE, NONZERO } public class CommandRunner { public static CRThrow DefaultThrow { get; set; } = CRThrow.NONZERO; public CRThrow Throw { get; set; } = DefaultThrow; public string Executable { get; } public string[] Arguments { get; set; } public string WorkingDirectory { get; set; } = "."; public Logger Logger { get; } public CommandRunner(string executable,params string[] arguments) : this(Logger.Default, executable, arguments){} public CommandRunner(Logger logger, string executable,params string[] arguments) { Logger = logger; Executable = executable; Arguments = arguments; } public string FindFileInPath(string filename) { Logger.Log(LogLevel.DEBUG, "Looking up {0} in paths {1}", filename, Environment.GetEnvironmentVariable("PATH")); foreach (string path in Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)) { string fullpath = Path.Combine(path,filename); if (File.Exists(fullpath)) return fullpath; } return filename; } public int Run() => Run(Logger, null, null); public int Run(Stream stdout, Stream stderr) => Run(Logger, stdout, stderr); public int Run(Logger logger, Stream stdout) => Run(logger, stdout, stdout); public int Run(Logger logger, Stream stdout, Stream stderr) { ProcessStartInfo psi = new ProcessStartInfo(FindFileInPath(Executable), string.Join(' ', Arguments)) { CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, RedirectStandardInput = true, WorkingDirectory = this.WorkingDirectory }; psi.EnvironmentVariables.Remove("LANG"); logger.Log(LogLevel.INFO, "Executing: {0} {1}", psi.FileName, psi.Arguments); Process process = Process.Start(psi); process.WaitForExit(); if (stdout != null) process.StandardOutput.BaseStream.CopyTo(stdout); if (stderr != null) process.StandardError.BaseStream.CopyTo(stderr); logger.Log(LogLevel.INFO, "Result: {0}", process.ExitCode); if ( ((Throw == CRThrow.NEGATIVE) && (process.ExitCode < 0)) || ((Throw == CRThrow.NONZERO) && (process.ExitCode != 0)) ) throw new Exception(String.Format("{0} execution gave result {1}", psi.FileName, process.ExitCode)); return process.ExitCode; } public int Run(out string stdout,out string stderr) => Run(Logger, out stdout, out stderr); public int Run(Logger logger, out string stdout,out string stderr) { MemoryStream outstream,errstream; outstream = new MemoryStream(); errstream = new MemoryStream(); int status = Run(logger, outstream, errstream); using (StreamReader sr = new StreamReader(outstream)) stdout = sr.ReadToEnd(); using (StreamReader sr = new StreamReader(errstream)) stderr = sr.ReadToEnd(); return status; } /* public static int Run(string executable,out Stream stdout,out Stream stderr,params string[] arguments) { CommandRunner runner = new CommandRunner(executable,arguments); return runner.Run(out stdout,out stderr); } public static int Run(string executable,out string stdout,out string stderr,params string[] arguments) => Run(Logger.Default, executable, out stdout, out stderr, arguments); public static int Run(Logger logger, string executable, out string stdout, out string stderr, params string[] arguments) { CommandRunner runner = new CommandRunner(logger, executable, arguments); int result = runner.Run(out stdout, out stderr); return result; } public static int Run(string executable,params string[] arguments) => Run(executable,out Stream stdout,out Stream stderr,arguments); public static int Run(Logger logger, string executable, params string[] arguments){ return Run(executable,out Stream stdout,out Stream stderr,arguments); } */ } }