Example #1
0
        public void Generate(ScriptContext context, TextWriter codeStream, Script script, GeneratorOptions options)
        {
            Compiler.AddHeaders("using XS = " + typeof(Script).Namespace + ";");

            ScriptContext sv = new ScriptContext();

            sv["main"]          = ((options & GeneratorOptions.CreateMain) != 0) ? genMain() : string.Empty;
            sv["assembly"]      = genAssemblyInfo(context, script, options);
            sv["namespace"]     = Namespace;
            sv["class"]         = Class;
            sv["src"]           = script.Location;
            sv["date"]          = DateTime.Now.ToString();
            sv["version"]       = context.CoreVersion.ToString();
            sv["script"]        = Compiler.GetTypeName(script.GetType());
            sv["callIsolation"] = Compiler.GetTypeName(typeof(CallIsolation));
            sv["iscriptaction"] = Compiler.GetTypeName(typeof(IScriptAction));
            sv["usings"]        = Compiler.GenerateFileHeader(true, false, false);
            sv["headers"]       = Compiler.GenerateFileHeader(false, true, false);
            sv["context"]       = Compiler.GetTypeName(context.GetType());
            using (StringWriter swCode = new StringWriter())
                using (StringWriter swSnippets = new StringWriter())
                    using (new ScriptContextScope(context))
                    {
                        Generator c = new Generator(Compiler, swCode, swSnippets, options);
                        c.GenerateObjectCode(script, "_script", 3);
                        sv["snippets-code"] = swSnippets.ToString();
                        sv["script-code"]   = swCode.ToString();
                    }
            using (MemoryStream ms = AppDomainLoader.TryLoadResourceStream("XSharper.Embedded.Source.SourceTemplate"))
                using (var sr = new StreamReader(ms))
                    codeStream.Write(sv.ExpandStr(sr.ReadToEnd()));
        }
Example #2
0
        static public int MainWithoutContext(string[] args)
        {
            AppDomainLoader.progress("MainWithoutContext: Entering");
            ScriptContext context = new ScriptContext(AppDomainLoader.ResourceAssembly);

            return(MainWithContext(context, args));
        }
Example #3
0
        static int Main(string[] args)
        {
            try
            {
                // Disable fatal error message popups by SetErrorMode(SEM_FAILCRITICALERRORS)
                try
                {
                    SetErrorMode(1);
                }
                catch (System.EntryPointNotFoundException)
                {
                }

                AppDomainLoader.progress("Main: Starting");
                AppDomain.CurrentDomain.UnhandledException += (a, b) => { AppDomainLoader.progress("Main: !!!" + b.IsTerminating); };
                int exitCode = AppDomainLoader.Loader(args) ?? MainWithoutContext(args);
                AppDomainLoader.progress("Main: Exiting with exit code " + exitCode);
                return(exitCode);
            }
            catch (System.Security.SecurityException)
            {
                Console.Error.WriteLine("Code security exception. Please copy XSharper to a local hard drive and try again.");
                return(-3);
            }
        }
Example #4
0
        private static int restartAsAdmin(ScriptContext context, string[] args, bool hidden)
        {
            context.WriteLine(OutputType.Info, "** Administrative privileges are required to run this script.\n** Please confirm to continue.");
            if (context.IsSet(xs.testElevation))
            {
                List <string> f = new List <string>();
                foreach (string s in args)
                {
                    if (string.Compare(s, xs.testElevation.Replace("xs.", "//"), StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        f.Add(s);
                    }
                }
                args = f.ToArray();
            }

            AppDomainLoader.progress("MainWithContext: About to restart with CmdLine=" + string.Join(" ", args));


            int n = AppDomainLoader.RunWithElevatedContext(
                delegate(ScriptContext ctx)
            {
                ScriptContextScope.DefaultContext = ctx;
                try
                {
                    if (!ctx.IsAdministrator)
                    {
                        throw new ScriptRuntimeException("Administrator privileges are required");
                    }
                    return(MainWithContext(ctx, args));
                }
                finally
                {
                    ScriptContextScope.DefaultContext = null;
                }
            }, hidden);

            if (n == -1)
            {
                throw new ScriptRuntimeException("An error occured while granting administrative privileges.");
            }
            if (n != 0)
            {
                throw new ScriptRuntimeException("An error occured during script execution.");
            }

            return(0);
        }
Example #5
0
        private static Script execGenerator(ScriptContext context, string c, string prefix, string suffix)
        {
            Script script = createEmptyScript(context, "generated");

            if (context.Compiler.DefaultNETVersion >= new Version(3, 5))
            {
                // Yeah, I know it's deprecated, and it's best to use full assembly names, but
                // but I don't really want to scan GAC myself
#pragma warning disable 618
                context.AddAssembly(Assembly.LoadWithPartialName("System.Xml.Linq"), false);
                context.AddAssembly(Assembly.LoadWithPartialName("System.Core"), false);
#pragma warning restore 618
            }
            script.Add(new Rem {
                Text = "----- Generated from command line -------" + Environment.NewLine + "\t" + c + Environment.NewLine + "\t ------------"
            });
            script.Parameters.Add(new CommandLineParameter("arg", CommandLineValueCount.Multiple)
            {
                Last = true, Default = "", Required = false
            });
            script.UnknownSwitches = true;

            c = c.Trim();
            if (c.StartsWith("\"", StringComparison.Ordinal) && c.EndsWith("\"", StringComparison.Ordinal))
            {
                c = c.Substring(1, c.Length - 2);
            }
            if (c == "-")
            {
                c = Console.In.ReadToEnd();
            }
            if (c.StartsWith("="))
            {
                prefix = "=" + prefix;
                c      = "${=" + c.Substring(1) + "}";
            }
            if (prefix != null || suffix != null)
            {
                c = prefix + Environment.NewLine + c + Environment.NewLine + suffix;
            }
            c = c.Replace("`", "\"");

            AppDomainLoader.progress("Read script begin");
            using (new ScriptContextScope(context))
                script.Load(c);
            AppDomainLoader.progress("Read script end");
            return(script);
        }
Example #6
0
 private static Script loadScript(string location, ScriptContext context)
 {
     AppDomainLoader.progress("MainWithContext: Parsing XML");
     try
     {
         byte[] data;
         bool   validate = context.GetBool(xs.validate, false);
         if (location == ".")
         {
             location = loadFromConfig(out data);
             return(context.LoadScript(new MemoryStream(data), location, validate));
         }
         else
         {
             return(context.LoadScript(location, validate));
         }
     }
     finally
     {
         AppDomainLoader.progress("MainWithContext: Parsing completed");
     }
 }
Example #7
0
        private StringBuilder extractContents(string streamName)
        {
            // formatted C# source code is easy to parse. Cut everything that is not using & namespace
            StringBuilder appDomainLoader = new StringBuilder();

            using (MemoryStream ms = AppDomainLoader.TryLoadResourceStream(streamName))
                using (var sr = new StreamReader(ms))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.Length == 0 || char.IsWhiteSpace(line[0]))
                        {
                            appDomainLoader.AppendLine(line);
                        }
                        else if (line.StartsWith("using", StringComparison.Ordinal))
                        {
                            Compiler.AddHeaders(line);
                        }
                    }
                }
            return(appDomainLoader);
        }
Example #8
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);
        }
Example #9
0
        private static void doCodeGeneration(ScriptContext context, Script script)
        {
            if (!isCodeGeneration(context))
            {
                return;
            }

            context.Compiler.AddReference(null, typeof(System.Runtime.Remoting.Channels.Ipc.IpcChannel).Assembly.FullName, false, false, null);

            if (context.IsSet(xs.save) && script != null)
            {
                context.WriteLine(OutputType.Info, string.Format("Saving script to {0} ...", context[xs.save]));
                using (new ScriptContextScope(context))
                    script.Save(context.GetString(xs.save));
                context.WriteLine(OutputType.Info, string.Format("Script file {0} saved...", context[xs.save]));
            }

            if (context.IsSet(xs.genxsd))
            {
                context.WriteLine(OutputType.Info, string.Format("Generating XML schema  ..."));

                XmlSchema x  = generateSchema(context);
                string    sf = context.GetString(xs.genxsd);
                sf = Path.GetFullPath((sf == "*") ? x.Id + ".xsd" : sf);
                using (StreamWriter target = new StreamWriter(sf, false))
                    x.Write(target);

                context.WriteLine(OutputType.Info, string.Format("XML schema saved to {0} ...", sf));
            }

            // Generate source code
            StringWriter source     = new StringWriter();
            string       entryPoint = null;

            if (script != null && (context.IsSet(xs.genlibrary) || context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.gencs)))
            {
                context.WriteLine(OutputType.Info, "Generating C# source code...");
                SharpCodeGenerator codeGenerator = new SharpCodeGenerator(context.Compiler);

                if (context.IsSet(xs.@namespace))
                {
                    codeGenerator.Namespace = context.GetString(xs.@namespace);
                }

                string baseName = Path.GetFileNameWithoutExtension(script.Location).ToLower();
                if (script.Id != null)
                {
                    baseName = script.Id;
                }
                baseName = Utils.FixFilename(baseName);

                if (context.IsSet(xs.@class))
                {
                    codeGenerator.Class = context.GetString(xs.@class);
                }
                else
                {
                    string cl;
                    cl = baseName;
                    if (char.IsDigit(cl[0]))
                    {
                        cl = "C" + cl;
                    }
                    if (!char.IsUpper(cl[0]))
                    {
                        cl = cl.Substring(0, 1).ToUpperInvariant() + cl.Substring(1);
                    }
                    cl = SharpCodeGenerator.ToValidName(cl);
                    if (cl == "Script" || cl == "Run")
                    {
                        cl = "C" + cl;
                    }
                    codeGenerator.Class = cl;
                }

                string pref = string.Empty;
                if (!string.IsNullOrEmpty(context.CodeOutputDirectory))
                {
                    pref = Path.Combine(context.CodeOutputDirectory, "bin\\Debug\\");
                }
                if (context.IsSet(xs.genexe) && context.GetString(xs.genexe) == "*")
                {
                    context[xs.genexe] = pref + baseName + ".exe";
                }
                if (context.IsSet(xs.genwinexe) && context.GetString(xs.genwinexe) == "*")
                {
                    context[xs.genwinexe] = pref + baseName + ".exe";
                }
                if (context.IsSet(xs.genlibrary) && context.GetString(xs.genlibrary) == "*")
                {
                    context[xs.genlibrary] = pref + baseName + ".dll";
                }
                if (context.IsSet(xs.gencs) && context.GetString(xs.gencs) == "*")
                {
                    context[xs.gencs] = baseName + ".cs";
                }

                GeneratorOptions options = GeneratorOptions.None;
                if (context.IsSet(xs.genexe))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain;
                }
                if (context.IsSet(xs.genwinexe))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain | GeneratorOptions.WinExe;
                }
                if (context.IsSet(xs.genlibrary))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe;
                }
                if (context.GetBool(xs.main, false))
                {
                    options |= GeneratorOptions.CreateMain;
                }
                if (context.GetBool(xs.forcenet20, false))
                {
                    options |= GeneratorOptions.ForceNet20;
                }
                if (context.CodeOutputDirectory == null && !context.IsSet(xs.gencs))
                {
                    options |= GeneratorOptions.ForceNet20; // this is a bit faster
                }
                if (context.GetBool(xs.noSrc, false))
                {
                    options &= ~GeneratorOptions.IncludeSource;
                }


                codeGenerator.Generate(context, source, script, options);
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                {
                    entryPoint = codeGenerator.Namespace + "." + codeGenerator.Class + "Program";
                }
            }

            // Save it to disk, if necessary
            string code = source.GetStringBuilder().ToString();

            if (script != null && context.IsSet(xs.gencs))
            {
                using (StreamWriter sourceDisk = new StreamWriter(context.GetString(xs.gencs), false))
                {
                    sourceDisk.Write(code);
                }
                context.WriteLine(OutputType.Info, string.Format("C# source code saved to {0} ...", context[xs.gencs]));
            }

            // Load the other part from resources
            if (script != null && (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.genlibrary)))
            {
                CompiledOutputType outType;
                string             e;
                if (context.IsSet(xs.genexe))
                {
                    e       = context.GetString(xs.genexe);
                    outType = CompiledOutputType.ConsoleExe;
                }
                else if (context.IsSet(xs.genwinexe))
                {
                    e       = context.GetString(xs.genwinexe);
                    outType = CompiledOutputType.WindowsExe;
                }
                else
                {
                    e       = context.GetString(xs.genlibrary);
                    outType = CompiledOutputType.Library;
                }

                context.WriteLine(OutputType.Info, string.Format("Compiling {0}...", e));


                var copt = new CompileOptions
                {
                    ExtraOptions        = context.GetString(xs.compilerOptions, null),
                    CodeOutputDirectory = context.CodeOutputDirectory,
                    StreamProvider      = context.FindResourceMemoryStream,
                    FilesToEmbed        = context.GetFilesToEmbed(),
                    EntryPoint          = entryPoint,
                };
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                {
                    if (script.RequireAdmin != RequireAdminMode.User)
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.manifest").ToArray();
                    }
                    else
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.manifest").ToArray();
                    }
                    if (context.IsSet(xs.icon))
                    {
                        copt.Icon = context.ReadBytes(context.GetStr(xs.icon));
                    }
                    else
                    {
                        copt.Icon = AppDomainLoader.TryLoadResourceStream(@"Source.xsh.ico").ToArray();
                    }
                }


                // If we're building .EXE, add a reference to ZipLib. We don't want to do it
                // unnecessarily to save time, and also allow XSharper.Core use w/o ZipLib, so the reference is added only if it's loaded

                foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (ass.FullName != null && ass.FullName.Contains("ICSharpCode.SharpZipLib"))
                    {
                        context.Compiler.AddReference(null, ass.FullName, true, false, null);
                        break;
                    }
                }

                context.Compiler.Compile(outType, code, e, copt);
                context.WriteLine(OutputType.Info, string.Format("Executable saved to {0} ...", e));
            }
        }