/// <summary> /// Creates the executor process instance /// </summary> public static Process Instance(string base_dir, string runner, string tool, string[] includes, string[] args) { string home = Environment.GetEnvironmentVariable("HOME"); // Read configuration XpConfigSource configs = new CompositeConfigSource( new EnvironmentConfigSource(), new IniConfigSource(new Ini(Paths.Compose(".", "xp.ini"))), null != home ? new IniConfigSource(new Ini(Paths.Compose(home, ".xp", "xp.ini"))) : null, new IniConfigSource(new Ini(Paths.Compose(Environment.SpecialFolder.LocalApplicationData, "Xp", "xp.ini"))), new IniConfigSource(new Ini(Paths.Compose(base_dir, "xp.ini"))) ); IEnumerable<string> use_xp = configs.GetUse(); string runtime = configs.GetRuntime(); string executor = configs.GetExecutable(runtime) ?? "php"; if (null == use_xp) { throw new EntryPointNotFoundException("Cannot determine use_xp setting from " + configs); } // Pass "USE_XP" and includes inside include_path separated by two path // separators. Prepend "." for the oddity that if the first element does // not exist, PHP scraps all the others(!) // // E.g.: -dinclude_path=".;xp\5.7.0;..\dialog;;..\impl.xar;..\log.xar" // ^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ // | | include_path // | USE_XP // Dot string argv = String.Format( "-C -q -dinclude_path=\".{1}{0}{1}{1}{2}\" -dmagic_quotes_gpc=0", String.Join(PATH_SEPARATOR, new List<string>(use_xp).ToArray()), PATH_SEPARATOR, String.Join(PATH_SEPARATOR, includes) ); // Look for PHP configuration foreach (KeyValuePair<string, IEnumerable<string>> kv in configs.GetArgs(runtime)) { foreach (string value in kv.Value) { argv += " -d" + kv.Key + "=\"" + value + "\""; } } // Add extensions IEnumerable<string> extensions= configs.GetExtensions(runtime); if (null != extensions) { foreach (var ext in extensions) { argv += " -dextension=" + ext; } } // Find entry point, which is either a file called [runner]-main.php, which // will receive the arguments in UTF-8, or a file called [runner].php, which // assumes the arguments come in in platform encoding. // // Windows encodes the command line arguments to platform encoding for PHP, // which doesn't define a "wmain()", so we'll need to double-encode our // $argv in a "binary-safe" way in order to transport Unicode into PHP. string entry; bool redirect; Argument argument; if (null != (entry = Paths.Find(use_xp, "tools\\" + runner + "-main.php"))) { argument = Encode; redirect = true; argv += " -dencoding=utf-7"; } else if (null != (entry = Paths.Find(use_xp, "tools\\" + runner + ".php"))) { argument = Pass; redirect = false; } else { throw new EntryPointNotFoundException("Cannot find tool in " + String.Join(", ", new List<string>(use_xp).ToArray())); } // Spawn runtime var proc = new Process(); proc.StartInfo.RedirectStandardOutput = redirect; proc.StartInfo.RedirectStandardError = redirect; proc.StartInfo.FileName = executor; proc.StartInfo.Arguments = argv + " \"" + entry + "\" " + tool; if (args.Length > 0) { foreach (string arg in args) { proc.StartInfo.Arguments += " " + argument(arg); } } // Catch Ctrl+C (only works in "real" consoles, not in a cygwin // shell, for example) and kill the spawned process, see also: // http://www.cygwin.com/ml/cygwin/2006-12/msg00151.html // http://www.mail-archive.com/[email protected]/msg74638.html Console.CancelKeyPress += (sender, e) => { proc.Kill(); proc.WaitForExit(); }; proc.StartInfo.UseShellExecute = false; return proc; }
/// <summary> /// /// </summary> /// <param name="base_dir"></param> /// <param name="runner"></param> /// <param name="tool"></param> /// <param name="includes"></param> /// <param name="args"></param> public static int Execute(string base_dir, string runner, string tool, string[] includes, string[] args) { string home = Environment.GetEnvironmentVariable("HOME"); // Read configuration XpConfigSource configs = new CompositeConfigSource( new EnvironmentConfigSource(), new IniConfigSource(new Ini(Paths.Compose(".", "xp.ini"))), null != home ? new IniConfigSource(new Ini(Paths.Compose(home, ".xp", "xp.ini"))) : null, new IniConfigSource(new Ini(Paths.Compose(Environment.SpecialFolder.LocalApplicationData, "Xp", "xp.ini"))), new IniConfigSource(new Ini(Paths.Compose(base_dir, "xp.ini"))) ); IEnumerable<string> use_xp = configs.GetUse(); string executor = configs.GetRuntime() ?? "php"; if (null == use_xp) { throw new EntryPointNotFoundException("Cannot determine use_xp setting from " + configs); } // Pass "USE_XP" and includes inside include_path separated by two path // separators. Prepend "." for the oddity that if the first element does // not exist, PHP scraps all the others(!) // // E.g.: -dinclude_path=".;xp\5.7.0;..\dialog;;..\impl.xar;..\log.xar" // ^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ // | | include_path // | USE_XP // Dot string argv = String.Format( "-C -q -dinclude_path=\".{1}{0}{1}{1}{2}\" -dmagic_quotes_gpc=0", String.Join(PATH_SEPARATOR, new List<string>(use_xp).ToArray()), PATH_SEPARATOR, String.Join(PATH_SEPARATOR, includes) ); // If input or output encoding are not equal to default, also pass their // names inside an LC_CONSOLE environment variable. Only do this inside // real Windows console windows! // // See http://msdn.microsoft.com/en-us/library/system.text.encoding.headername.aspx // and http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx if (null == Environment.GetEnvironmentVariable("TERM")) { Encoding defaultEncoding = Encoding.Default; if (!defaultEncoding.Equals(Console.InputEncoding) || !defaultEncoding.Equals(Console.OutputEncoding)) { Environment.SetEnvironmentVariable("LC_CONSOLE", Console.InputEncoding.HeaderName + "," + Console.OutputEncoding.HeaderName); } } // Look for PHP configuration foreach (KeyValuePair<string, IEnumerable<string>> kv in configs.GetArgs()) { foreach (string value in kv.Value) { argv += " -d" + kv.Key + "=\"" + value + "\""; } } // Spawn runtime var proc = new Process(); proc.StartInfo.FileName = executor; proc.StartInfo.Arguments = argv + " \"" + new List<string>(Paths.Locate(use_xp, "tools\\" + runner + ".php", true))[0] + "\" " + tool; if (args.Length > 0) { foreach (string arg in args) { proc.StartInfo.Arguments += " \"" + arg.Replace("\"", "\"\"\"") + "\""; } } // Catch Ctrl+C (only works in "real" consoles, not in a cygwin // shell, for example) and kill the spawned process, see also: // http://www.cygwin.com/ml/cygwin/2006-12/msg00151.html // http://www.mail-archive.com/[email protected]/msg74638.html Console.CancelKeyPress += delegate { proc.Kill(); proc.WaitForExit(); }; proc.StartInfo.UseShellExecute = false; try { proc.Start(); proc.WaitForExit(); return proc.ExitCode; } catch (SystemException e) { throw new ExecutionEngineException(executor + ": " + e.Message, e); } finally { proc.Close(); } }
/// <summary> /// Creates the executor process instance /// </summary> public static Process Instance(string base_dir, string runner, string tool, string[] modules, string[] includes, string[] args) { string home = Environment.GetEnvironmentVariable("HOME"); // Read configuration XpConfigSource configs = new CompositeConfigSource( new EnvironmentConfigSource(), new IniConfigSource(new Ini(Paths.Compose(".", "xp.ini"))), null != home ? new IniConfigSource(new Ini(Paths.Compose(home, ".xp", "xp.ini"))) : null, new IniConfigSource(new Ini(Paths.Compose(Environment.SpecialFolder.LocalApplicationData, "Xp", "xp.ini"))), new IniConfigSource(new Ini(Paths.Compose(base_dir, "xp.ini"))) ); IEnumerable <string> use_xp = configs.GetUse(); string runtime = configs.GetRuntime(); string executor = configs.GetExecutable(runtime) ?? "php"; if (null == use_xp) { throw new EntryPointNotFoundException("Cannot determine use_xp setting from " + configs); } // Pass "USE_XP" and includes inside include_path separated by two path // separators. Prepend "." for the oddity that if the first element does // not exist, PHP scraps all the others(!) // // E.g.: -dinclude_path=".;xp\5.7.0;..\dialog;;..\impl.xar;..\log.xar" // ^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ // | | include_path // | USE_XP // Dot string argv = String.Format( "-C -q -d include_path=\".{0}{1}{0}{2}{0}{0}{3}\" -d magic_quotes_gpc=0", PATH_SEPARATOR, String.Join(PATH_SEPARATOR, use_xp), String.Join(PATH_SEPARATOR, modules), String.Join(PATH_SEPARATOR, includes) ); // Look for PHP configuration foreach (KeyValuePair <string, IEnumerable <string> > kv in configs.GetArgs(runtime)) { foreach (string value in kv.Value) { argv += " -d " + kv.Key + "=\"" + value + "\""; } } // Add extensions IEnumerable <string> extensions = configs.GetExtensions(runtime); if (null != extensions) { foreach (var ext in extensions) { argv += " -d extension=" + ext; } } // Find entry point, which is either a file called [runner]-main.php, which // will receive the arguments in UTF-8, or a file called [runner].php, which // assumes the arguments come in in platform encoding. // // Windows encodes the command line arguments to platform encoding for PHP, // which doesn't define a "wmain()", so we'll need to double-encode our // $argv in a "binary-safe" way in order to transport Unicode into PHP. string entry; bool redirect; Argument argument; if (null != (entry = Paths.Find(use_xp, "tools\\" + runner + ".php"))) { argument = Pass; redirect = false; } else if (null != (entry = Paths.Find(new string[] { base_dir }, runner + "-main.php"))) { argument = Encode; redirect = true; } else { throw new EntryPointNotFoundException("Cannot find tool in " + String.Join(", ", new List <string>(use_xp).ToArray())); } // Spawn runtime var proc = new Process(); proc.StartInfo.RedirectStandardOutput = redirect; proc.StartInfo.RedirectStandardError = redirect; proc.StartInfo.FileName = executor; proc.StartInfo.Arguments = argv + " \"" + entry + "\" " + tool; if (args.Length > 0) { foreach (string arg in args) { proc.StartInfo.Arguments += " " + argument(arg); } } // Catch Ctrl+C (only works in "real" consoles, not in a cygwin // shell, for example) and kill the spawned process, see also: // http://www.cygwin.com/ml/cygwin/2006-12/msg00151.html // http://www.mail-archive.com/[email protected]/msg74638.html Console.CancelKeyPress += (sender, e) => { proc.Kill(); proc.WaitForExit(); }; proc.StartInfo.UseShellExecute = false; return(proc); }
/// <summary> /// /// </summary> /// <param name="base_dir"></param> /// <param name="runner"></param> /// <param name="tool"></param> /// <param name="includes"></param> /// <param name="args"></param> public static Process Instance(string base_dir, string runner, string tool, string[] includes, string[] args) { string home = Environment.GetEnvironmentVariable("HOME"); // Read configuration XpConfigSource configs = new CompositeConfigSource( new EnvironmentConfigSource(), new IniConfigSource(new Ini(Paths.Compose(".", "xp.ini"))), null != home ? new IniConfigSource(new Ini(Paths.Compose(home, ".xp", "xp.ini"))) : null, new IniConfigSource(new Ini(Paths.Compose(Environment.SpecialFolder.LocalApplicationData, "Xp", "xp.ini"))), new IniConfigSource(new Ini(Paths.Compose(base_dir, "xp.ini"))) ); IEnumerable <string> use_xp = configs.GetUse(); string runtime = configs.GetRuntime(); string executor = configs.GetExecutable(runtime) ?? "php"; if (null == use_xp) { throw new EntryPointNotFoundException("Cannot determine use_xp setting from " + configs); } // Pass "USE_XP" and includes inside include_path separated by two path // separators. Prepend "." for the oddity that if the first element does // not exist, PHP scraps all the others(!) // // E.g.: -dinclude_path=".;xp\5.7.0;..\dialog;;..\impl.xar;..\log.xar" // ^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ // | | include_path // | USE_XP // Dot string argv = String.Format( "-C -q -dinclude_path=\".{1}{0}{1}{1}{2}\" -dmagic_quotes_gpc=0", String.Join(PATH_SEPARATOR, new List <string>(use_xp).ToArray()), PATH_SEPARATOR, String.Join(PATH_SEPARATOR, includes) ); // If input or output encoding are not equal to default, also pass their // names inside an LC_CONSOLE environment variable. Only do this inside // real Windows console windows! // // See http://msdn.microsoft.com/en-us/library/system.text.encoding.headername.aspx // and http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx if (null == Environment.GetEnvironmentVariable("TERM")) { Encoding defaultEncoding = Encoding.Default; if (!defaultEncoding.Equals(Console.InputEncoding) || !defaultEncoding.Equals(Console.OutputEncoding)) { Environment.SetEnvironmentVariable("LC_CONSOLE", Console.InputEncoding.HeaderName + "," + Console.OutputEncoding.HeaderName); } } // Look for PHP configuration foreach (KeyValuePair <string, IEnumerable <string> > kv in configs.GetArgs(runtime)) { foreach (string value in kv.Value) { argv += " -d" + kv.Key + "=\"" + value + "\""; } } // Add extensions IEnumerable <string> extensions = configs.GetExtensions(runtime); if (null != extensions) { foreach (var ext in extensions) { argv += " -dextension=" + ext; } } // Spawn runtime var proc = new Process(); proc.StartInfo.FileName = executor; proc.StartInfo.Arguments = argv + " \"" + new List <string>(Paths.Locate(use_xp, "tools\\" + runner + ".php", true))[0] + "\" " + tool; if (args.Length > 0) { foreach (string arg in args) { proc.StartInfo.Arguments += " \"" + arg.Replace("\"", "\"\"\"") + "\""; } } // Catch Ctrl+C (only works in "real" consoles, not in a cygwin // shell, for example) and kill the spawned process, see also: // http://www.cygwin.com/ml/cygwin/2006-12/msg00151.html // http://www.mail-archive.com/[email protected]/msg74638.html Console.CancelKeyPress += delegate { proc.Kill(); proc.WaitForExit(); }; proc.StartInfo.UseShellExecute = false; return(proc); }