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())); }
static public int MainWithoutContext(string[] args) { AppDomainLoader.progress("MainWithoutContext: Entering"); ScriptContext context = new ScriptContext(AppDomainLoader.ResourceAssembly); return(MainWithContext(context, args)); }
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); } }
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); }
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); }
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"); } }
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); }
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); }
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)); } }