Beispiel #1
0
        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;
        }
Beispiel #2
0
        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;
        }