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)); } }