static int MainWithContext(ScriptContext context, string[] args) { CommandLineParameters xsParams = getXsParams(); int exitCode = 0; ConsoleRedirector redir = null; AppDomainLoader.progress("MainWithContext: Entering --------------------"); bool utf8 = false; foreach (string arg in args) if (arg.Equals(xs.utf8.Replace("xs.", "//"), StringComparison.OrdinalIgnoreCase)) utf8 = true; using (ConsoleWithColors cout = new ConsoleWithColors(Environment.GetEnvironmentVariable("XSH_COLORS"),utf8)) using (CtrlCInterceptor ctrl = new CtrlCInterceptor()) { context.Output += cout.OnOutput; ctrl.Output = context.Error; ctrl.Abort += delegate { context.Abort(); }; Stopwatch w = Stopwatch.StartNew(); try { // Parse arguments var usage = new UsageGenerator() { Options = UsageOptions.None }; xsParams.Parse(context, args, false); setOutputOptions(context, cout); if (context.IsSet(xs.path)) context.ScriptPath = context.GetString(xs.path); // Load references List<IScriptAction> preScript = getCommandlineReferences(context); // Print help if (args.Length == 0 || context.IsSet(xs.help)) { loadReferences(context,preScript); exitCode = HelpHelper.Help(context, usage , xsParams); goto end; } // Handle upgrade if (context.GetBool(xs.upgrade, false)) { return upgrade(context);} if (context.IsSet(xs.updateStage)) { return updateStage(context, context.GetStringArray(xs.updateStage));} AppDomainLoader.progress("MainWithContext: Processing options"); // Process the remaining options context.Compiler.AddRequireAdmin(Utils.To<RequireAdminMode>(context.GetStr(xs.requireAdmin, RequireAdminMode.User.ToString()))); if (context.IsSet(xs.codeout)) context.CodeOutputDirectory = Path.GetFullPath(context.GetString(xs.codeout)); if (context.IsSet(xs.genconfig) || context.IsSet(xs.gensample)) genDemoConfig(cout, context); if (context.IsSet(xs.forcenet20)) context.Compiler.DefaultNETVersion = new Version(2,0); AppDomainLoader.progress("MainWithContext: Processing options, continuing"); List<string> filteredArgs = new List<string>(); if (context.IsSet(xs.scriptargs)) filteredArgs.AddRange(context.GetStringArray(xs.scriptargs)); // Run utilities, like //download etc Script script= getInlineScript(context, filteredArgs); string scriptName = context.GetString(xs.script, null); if (script == null) { // Load the script if (scriptName == "/?" || scriptName == "-?") { for (int i = 0; i < args.Length;++i ) if (args[i] == "/?" || args[i]=="-?") { if (i != args.Length - 1) context[xs.help] = args[i + 1]; break; } loadReferences(context, preScript); return HelpHelper.Help(context, usage, xsParams); } if (scriptName != null) { AppDomainLoader.progress("MainWithContext: Loading script " + scriptName); script = loadScript(scriptName, context); AppDomainLoader.progress("MainWithContext: Loading completed"); } } AppDomainLoader.progress("MainWithContext: About to initialize"); // Attach script if (script != null) { // Insert pre-script before the script body int n = 0; foreach (var list in preScript) script.Items.Insert(n++, list); AppDomainLoader.BaseDirectory = script.DirectoryName; RequireAdminMode mode = context.Compiler.RequireAdmin; if ((!context.IsAdministrator || context.GetBool(xs.testElevation, false)) && !isCodeGeneration(context) && mode!=RequireAdminMode.User) { return restartAsAdmin(context, args, mode==RequireAdminMode.Hidden && !(context.GetBool(xs.testElevation, false))); } AppDomainLoader.progress("MainWithContext: Before script initialization"); if (isCodeGeneration(context)) { if (!context.EnableCodePrecompilation && (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.genlibrary) || context.IsSet(xs.gencs))) throw new ParsingException("One of the loaded scripts has precompilation disabled. Executable cannot be generated from this script."); context.EnableCodePrecompilation = false; } ctrl.IgnoreCtrlC = script.IgnoreCtrlC; ctrl.AbortDelay = Utils.ToTimeSpan(script.AbortDelay) ?? ctrl.AbortDelay; ctrl.ExitDelay = Utils.ToTimeSpan(script.ExitDelay) ?? ctrl.ExitDelay; context.Initialize(script); AppDomainLoader.progress("MainWithContext: Script initialization completed"); } // After precompilation we're ready to write .exe, if requested if (isCodeGeneration(context)) { doCodeGeneration(context, script); } else if (script != null) { // Run the script AppDomainLoader.progress("MainWithContext: Before script execution"); redir = new ConsoleRedirector(context); try { object r = context.ExecuteScript(script, filteredArgs.ToArray(), CallIsolation.High); if (r != null) int.TryParse(r.ToString(), out exitCode); } finally { ctrl.KillAbortTimer(); redir.Dispose(); redir = null; } AppDomainLoader.progress("MainWithContext: Script execution completed"); } } catch (ThreadAbortException ae) { AppDomainLoader.progress("MainWithContext: ThreadAbortException is being aborted"); resetAbort(context); context.WriteException(ae); exitCode = -1; } catch(ScriptTerminateException te) { exitCode = te.ExitCode; resetAbort(context); if (te.InnerException != null) { context.WriteException(te.InnerException); AppDomainLoader.progress("MainWithContext: " + te.InnerException); } AppDomainLoader.progress("MainWithContext: Terminating with exit code " + exitCode); } catch (Exception e) { exitCode = -1; resetAbort(context); context.WriteException(e); AppDomainLoader.progress("MainWithContext: " + e); } finally { resetAbort(context); AppDomainLoader.BaseDirectory = null; } end: // Display how long did it take w.Stop(); if (context.GetBool(xs.wait,false)) { cout.WriteLine(OutputType.Info,string.Format("Completed in {0} with exit code={1}. Press Enter to close...", w.Elapsed, exitCode)); Console.ReadLine(); } } AppDomainLoader.progress("MainWithContext: Exiting with code "+exitCode); return exitCode; }
public static int Help(ScriptContext context, UsageGenerator usage, CommandLineParameters xsParams) { context.WriteLine(OutputType.Bold, GetLogo(context)); context.WriteLine(); var command = context.GetStr(xs.help, null); if (!string.IsNullOrEmpty(command)) { var tt = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase); tt["param"] = typeof (CommandLineParameter); tt["versionInfo"] = typeof(VersionInfo); tt["usage"] = typeof(UsageGenerator); foreach (var s in context.GetKnownTypes()) { foreach (var at in CustomAttributeHelper.All<XsTypeAttribute>(s)) if (!string.IsNullOrEmpty(at.Name)) tt[at.Name] = s; } Type type; if (tt.TryGetValue(command,out type)) { writeCommandHelp(context, type, usage.CorrectWidth(-1)); return -2; } if (command == "*") { List<Var> v = new List<Var>(); v.Add(new Var("param",getDescr(typeof(CommandLineParameter)))); v.Add(new Var("versioninfo", getDescr(typeof(VersionInfo)))); v.Add(new Var("usage", getDescr(typeof(UsageGenerator)))); foreach (var s in context.GetKnownTypes()) { var xst = CustomAttributeHelper.First<XsTypeAttribute>(s); if (xst == null || string.IsNullOrEmpty(xst.Name)) continue; v.Add(new Var(xst.Name, getDescr(s))); } v.Sort((a, b) => string.Compare(a.Name, b.Name)); v.Insert(0, new Var("Actions:", null)); v.Insert(1, new Var("", null)); Utils.WrapTwoColumns(context.Out, v, 30, usage.CorrectWidth(-1)); return -2; } if (command.StartsWith(".", StringComparison.Ordinal)) { bool success = false; foreach (var nn in ((IEvaluationContext)context).GetNonameObjects()) { success =writeTypeHelp(context, nn.Type, new StringFilter(command.Substring(1)),usage.CorrectWidth(-1)) || success; } if (!success) context.Error.WriteLine("Cannot find method '" + command + "'. "); return -2; } Type t = context.FindType(command); if (t == null) t = context.FindType("XS." + command); if (t != null) writeTypeHelp(context, t, null, usage.CorrectWidth(-1)); else if (command.Contains("?") || command.Contains("*")) { var r = Utils.WildcardToRegex(command, RegexOptions.IgnoreCase); foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) foreach (var ttt in a.GetTypes()) if (ttt != null && ttt.IsPublic && (r.IsMatch(ttt.Name) || r.IsMatch(Dump.GetFriendlyTypeName(ttt)))) { context.WriteLine(Dump.GetFriendlyTypeName(ttt,true)); } } else context.Error.WriteLine("Cannot find command or type '" + command + "'. Use //help * to display the list of commands"); } else context.WriteLine(usage.GetUsage(context, null, null, -1, xsParams)); return -2; }