private Assembly _universe_AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) { AssemblyName name = new AssemblyName(args.Name); AssemblyName previousMatch = null; int previousMatchLevel = 0; foreach (Assembly asm in _universe.GetAssemblies()) { if (Match(asm.GetName(), name, ref previousMatch, ref previousMatchLevel)) { return(asm); } } foreach (string file in FindAssemblyPath(name.Name + ".dll")) { if (Match(AssemblyName.GetAssemblyName(file), name, ref previousMatch, ref previousMatchLevel)) { return(LoadFile(file)); } } if (args.RequestingAssembly != null) { string path = Path.Combine(Path.GetDirectoryName(args.RequestingAssembly.Location), name.Name + ".dll"); if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel)) { return(LoadFile(path)); } } string hintpath; if (_hintpaths.TryGetValue(name.FullName, out hintpath)) { string path = Path.Combine(hintpath, name.Name + ".dll"); if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel)) { return(LoadFile(path)); } } if (previousMatch != null) { if (previousMatchLevel == 2) { ConsoleOps.Warning("assuming assembly reference '{0}' matches '{1}', you may need to supply runtime policy", previousMatch.FullName, name.FullName); return(LoadFile(new Uri(previousMatch.CodeBase).LocalPath)); } else if (args.RequestingAssembly != null) { ConsoleOps.Error(true, "Assembly '{0}' uses '{1}' which has a higher version than referenced assembly '{2}'", args.RequestingAssembly.FullName, name.FullName, previousMatch.FullName); } else { ConsoleOps.Error(true, "Assembly '{0}' was requested which is a higher version than referenced assembly '{1}'", name.FullName, previousMatch.FullName); } } else { ConsoleOps.Error(true, "unable to find assembly '{0}' {1}", args.Name, args.RequestingAssembly != null ? string.Format(" (a dependency of '{0}')", args.RequestingAssembly.FullName) : string.Empty); } return(null); }
static int Main(string[] args) { var files = new List <string>(); var config = new Config(); config.ParseArgs(args); if (!config.Validate()) { ConsoleOps.Usage(true); } ConsoleOps.Info("{0}", config); ConsoleOps.Info("compiling..."); // we don't use the engine, but we create it so we can have a default context. ScriptEngine engine = Python.CreateEngine(); ClrModule.CompileModules(DefaultContext.DefaultCLS, config.Output + ".dll", new Dictionary <string, object> { { "mainModule", config.MainName } }, config.Files.ToArray()); if (config.Target != PEFileKinds.Dll) { GenerateExe(config); } ConsoleOps.Info("Saved to {0}", config.Output); return(0); }
private Assembly LoadFile(string path) { string ex = null; try { using (RawModule module = _universe.OpenRawModule(path)) { if (_mscorlibVersion != null) { // to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of mscorlib foreach (AssemblyName asmref in module.GetReferencedAssemblies()) { if (asmref.Name == "mscorlib" && asmref.Version > _mscorlibVersion) { ConsoleOps.Error(true, "unable to load assembly '{0}' as it depends on a higher version of mscorlib than the one currently loaded", path); } } } Assembly asm = _universe.LoadAssembly(module); if (asm.Location != module.Location && CanonicalizePath(asm.Location) != CanonicalizePath(module.Location)) { ConsoleOps.Warning("assembly '{0}' is ignored as previously loaded assembly '{1}' has the same identity '{2}'", path, asm.Location, asm.FullName); } return(asm); } } catch (IOException x) { ex = x.Message; } catch (UnauthorizedAccessException x) { ex = x.Message; } catch (IKVM.Reflection.BadImageFormatException x) { ex = x.Message; } ConsoleOps.Error(true, "unable to load assembly '{0}'" + Environment.NewLine + " ({1})", path, ex); return(null); }
private IEnumerable <string> FindAssemblyPath(string file) { if (Path.IsPathRooted(file)) { if (File.Exists(file)) { yield return(file); } } else { foreach (string dir in _libpaths) { string path = Path.Combine(dir, file); if (File.Exists(path)) { yield return(path); } // for legacy compat, we try again after appending .dll path = Path.Combine(dir, file + ".dll"); if (File.Exists(path)) { ConsoleOps.Warning("Found assembly '{0}' using legacy search rule, please append '.dll' to the reference", file); yield return(path); } } } }
public bool Validate() { if (Files.Count == 1 && string.IsNullOrWhiteSpace(MainName)) { MainName = Files[0]; } if (Files.Count == 0 && !string.IsNullOrWhiteSpace(MainName)) { Files.Add(MainName); } if (Files == null || Files.Count == 0 || string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("No files or main defined"); return(false); } if (Target != PEFileKinds.Dll && string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("EXEs require /main:<filename> to be specified"); return(false); } if (DLLs.Count > 0 && !Standalone) { ConsoleOps.Error("DLLs can only be used in standalone mode"); return(false); } if (string.IsNullOrWhiteSpace(Output) && !string.IsNullOrWhiteSpace(MainName)) { Output = Path.GetFileNameWithoutExtension(MainName); OutputPath = Path.GetDirectoryName(MainName); } else if (string.IsNullOrWhiteSpace(Output) && Files != null && Files.Count > 0) { Output = Path.GetFileNameWithoutExtension(Files[0]); OutputPath = Path.GetDirectoryName(Files[0]); } if (!string.IsNullOrWhiteSpace(Win32Icon) && Target == PEFileKinds.Dll) { ConsoleOps.Error("DLLs may not have a win32icon"); return(false); } else if (!string.IsNullOrWhiteSpace(Win32Icon) && !File.Exists(Win32Icon)) { ConsoleOps.Error($"win32icon '{Win32Icon}' does not exist"); return(false); } return(true); }
public AssemblyResolver(Universe universe, bool nostdlib, IEnumerable <string> references, IEnumerable <string> libpaths) { _universe = universe; _libpaths.Add(Environment.CurrentDirectory); _libpaths.AddRange(libpaths); if (!nostdlib) { _libpaths.Add(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()); } // items passed in via /lib:<path> foreach (string path in libpaths) { foreach (string dir in path.Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries)) { if (Directory.Exists(dir)) { _libpaths.Add(dir); } else { ConsoleOps.Warning("Directory specified ('{0}') by /lib: does not exist", dir); } } } string envLib = Environment.GetEnvironmentVariable("LIB"); if (!string.IsNullOrEmpty(envLib)) { foreach (string dir in envLib.Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries)) { if (Directory.Exists(dir)) { _libpaths.Add(dir); } else { ConsoleOps.Warning("Directory specified ('{0}') in LIB does not exist", dir); } } } if (nostdlib) { _mscorlibVersion = LoadMscorlib(references).GetName().Version; } else { _mscorlibVersion = universe.Load("mscorlib").GetName().Version; } _universe.AssemblyResolve += _universe_AssemblyResolve; }
public static int Main(string[] args) { var files = new List <string>(); var config = new Config(); config.ParseArgs(args); if (!config.Validate()) { ConsoleOps.Usage(true); } // we don't use the engine, but we create it so we can have a default context. ScriptEngine engine = Python.CreateEngine(config.PythonOptions); ConsoleOps.Info($"IronPython Compiler for {engine.Setup.DisplayName} ({engine.LanguageVersion})"); ConsoleOps.Info($"{config}"); ConsoleOps.Info("compiling..."); var compileOptions = new Dictionary <string, object>() { { "mainModule", config.MainName }, { "assemblyFileVersion", config.FileVersion }, { "copyright", config.Copyright }, { "productName", config.ProductName }, { "productVersion", config.ProductVersion }, }; try { ClrModule.CompileModules(DefaultContext.DefaultCLS, Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".dll")), compileOptions, config.Files.ToArray()); var outputfilename = Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".dll")); if (config.Target != PEFileKinds.Dll) { outputfilename = Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".exe")); GenerateExe(config); } ConsoleOps.Info($"Saved to {outputfilename}"); } catch (Exception e) { Console.WriteLine(); ConsoleOps.Error(true, e.Message); } return(0); }
public bool Validate() { if (Files.Count == 1 && string.IsNullOrEmpty(MainName)) { MainName = Files[0]; } if (Files == null || Files.Count == 0 || string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("No files or main defined"); return(false); } if (Target != PEFileKinds.Dll && string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("EXEs require /main:<filename> to be specified"); return(false); } if (string.IsNullOrEmpty(Output) && !string.IsNullOrEmpty(MainName)) { Output = Path.GetFileNameWithoutExtension(MainName); } else if (string.IsNullOrEmpty(Output) && Files != null && Files.Count > 0) { Output = Path.GetFileNameWithoutExtension(Files[0]); } if (!string.IsNullOrEmpty(Win32Icon) && Target == PEFileKinds.Dll) { ConsoleOps.Error("DLLs may not have a win32icon"); return(false); } else if (!string.IsNullOrEmpty(Win32Icon) && !File.Exists(Win32Icon)) { ConsoleOps.Error("win32icon '{0}' does not exist", Win32Icon); return(false); } return(true); }
private Assembly LoadMscorlib(IEnumerable <string> references) { if (references != null) { foreach (string r in references) { try { if (AssemblyName.GetAssemblyName(r).Name == "mscorlib") { return(LoadFile(r)); } } catch { } } } foreach (string mscorlib in FindAssemblyPath("mscorlib.dll")) { return(LoadFile(mscorlib)); } ConsoleOps.Error(true, "unable to find mscorlib.dll"); return(null); }
/// <summary> /// Generates the stub .exe file for starting the app /// </summary> /// <param name="config"></param> private static void GenerateExe(Config config) { var u = new Universe(); var aName = new AssemblyName(Path.GetFileNameWithoutExtension(new FileInfo(config.Output).Name)); var ab = u.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save, config.OutputPath); var mb = ab.DefineDynamicModule(config.Output, aName.Name + (aName.Name.EndsWith(".exe") ? string.Empty : ".exe")); var tb = mb.DefineType("PythonMain", IKVM.Reflection.TypeAttributes.Public); if (!string.IsNullOrEmpty(config.Win32Icon)) { ab.__DefineIconResource(File.ReadAllBytes(config.Win32Icon)); } var attributes = new List <Tuple <string, Type> > { Tuple.Create(config.FileVersion, u.Import(typeof(System.Reflection.AssemblyFileVersionAttribute))), Tuple.Create(config.ProductName, u.Import(typeof(System.Reflection.AssemblyProductAttribute))), Tuple.Create(config.ProductVersion, u.Import(typeof(System.Reflection.AssemblyInformationalVersionAttribute))), Tuple.Create(config.Copyright, u.Import(typeof(System.Reflection.AssemblyCopyrightAttribute))) }; foreach (var attr in attributes) { if (!string.IsNullOrWhiteSpace(config.FileVersion)) { CustomAttributeBuilder builder = new CustomAttributeBuilder(attr.Item2.GetConstructor(new[] { u.Import(typeof(string)) }), new object[] { attr.Item1 }); ab.SetCustomAttribute(builder); } } ab.DefineVersionInfoResource(); MethodBuilder assemblyResolveMethod = null; ILGenerator gen = null; if (config.Standalone) { ConsoleOps.Info("Generating stand alone executable"); config.Embed = true; foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies()) { var n = new AssemblyName(a.FullName); if (!a.IsDynamic && a.EntryPoint == null && (n.Name.StartsWith("IronPython") || n.Name == "Microsoft.Dynamic" || n.Name == "Microsoft.Scripting")) { ConsoleOps.Info($"\tEmbedded {n.Name} {n.Version}"); var f = new FileStream(a.Location, FileMode.Open, FileAccess.Read); mb.DefineManifestResource("Dll." + n.Name, f, IKVM.Reflection.ResourceAttributes.Public); } } foreach (var dll in config.DLLs) { var name = Path.GetFileNameWithoutExtension(dll); ConsoleOps.Info($"\tEmbedded {name}"); var f = new FileStream(dll, FileMode.Open, FileAccess.Read); mb.DefineManifestResource("Dll." + name, f, IKVM.Reflection.ResourceAttributes.Public); } // we currently do no error checking on what is passed in to the assemblyresolve event handler assemblyResolveMethod = tb.DefineMethod("AssemblyResolve", MethodAttributes.Public | MethodAttributes.Static, u.Import(typeof(System.Reflection.Assembly)), new IKVM.Reflection.Type[] { u.Import(typeof(System.Object)), u.Import(typeof(System.ResolveEventArgs)) }); gen = assemblyResolveMethod.GetILGenerator(); var s = gen.DeclareLocal(u.Import(typeof(System.IO.Stream))); // resource stream gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Stloc, s); var d = gen.DeclareLocal(u.Import(typeof(byte[]))); // data buffer; gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes); gen.Emit(OpCodes.Ldstr, "Dll."); gen.Emit(OpCodes.Ldarg_1); // The event args gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.ResolveEventArgs)).GetMethod("get_Name"), Type.EmptyTypes); gen.Emit(OpCodes.Newobj, u.Import(typeof(System.Reflection.AssemblyName)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)) })); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.AssemblyName)).GetMethod("get_Name"), Type.EmptyTypes); gen.EmitCall(OpCodes.Call, u.Import(typeof(string)).GetMethod("Concat", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetManifestResourceStream", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes); gen.Emit(OpCodes.Stloc, s); gen.Emit(OpCodes.Ldloc, s); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("get_Length"), Type.EmptyTypes); gen.Emit(OpCodes.Newarr, u.Import(typeof(System.Byte))); gen.Emit(OpCodes.Stloc, d); gen.Emit(OpCodes.Ldloc, s); gen.Emit(OpCodes.Ldloc, d); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ldloc, s); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("get_Length"), Type.EmptyTypes); gen.Emit(OpCodes.Conv_I4); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("Read", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])), u.Import(typeof(int)), u.Import(typeof(int)) }), Type.EmptyTypes); gen.Emit(OpCodes.Pop); gen.Emit(OpCodes.Ldloc, d); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("Load", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])) }), Type.EmptyTypes); gen.Emit(OpCodes.Ret); // generate a static constructor to assign the AssemblyResolve handler (otherwise it tries to use IronPython before it adds the handler) // the other way of handling this would be to move the call to InitializeModule into a separate method. var staticConstructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); gen = staticConstructor.GetILGenerator(); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.AppDomain)).GetMethod("get_CurrentDomain"), Type.EmptyTypes); gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Ldftn, assemblyResolveMethod); gen.Emit(OpCodes.Newobj, u.Import(typeof(System.ResolveEventHandler)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(object)), u.Import(typeof(System.IntPtr)) })); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.AppDomain)).GetMethod("add_AssemblyResolve"), Type.EmptyTypes); gen.Emit(OpCodes.Ret); } var mainMethod = tb.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, u.Import(typeof(int)), Type.EmptyTypes); if (config.Target == PEFileKinds.WindowApplication && config.UseMta) { mainMethod.SetCustomAttribute(u.Import(typeof(System.MTAThreadAttribute)).GetConstructor(Type.EmptyTypes), new byte[0]); } else if (config.Target == PEFileKinds.WindowApplication) { mainMethod.SetCustomAttribute(u.Import(typeof(System.STAThreadAttribute)).GetConstructor(Type.EmptyTypes), new byte[0]); } gen = mainMethod.GetILGenerator(); // variables for saving original working directory and return code of script var strVar = gen.DeclareLocal(u.Import(typeof(string))); var intVar = gen.DeclareLocal(u.Import(typeof(int))); LocalBuilder dictVar = null; if (config.PythonOptions.Count > 0) { var True = u.Import(typeof(ScriptingRuntimeHelpers)).GetField("True"); var False = u.Import(typeof(ScriptingRuntimeHelpers)).GetField("False"); dictVar = gen.DeclareLocal(u.Import(typeof(Dictionary <string, object>))); gen.Emit(OpCodes.Newobj, u.Import(typeof(Dictionary <string, object>)).GetConstructor(Type.EmptyTypes)); gen.Emit(OpCodes.Stloc, dictVar); foreach (var option in config.PythonOptions) { gen.Emit(OpCodes.Ldloc, dictVar); gen.Emit(OpCodes.Ldstr, option.Key); if (option.Value is int val) { if (val >= -128 && val <= 127) { gen.Emit(OpCodes.Ldc_I4_S, val); // this is more optimized } else { gen.Emit(OpCodes.Ldc_I4, val); } gen.Emit(OpCodes.Box, u.Import(typeof(System.Int32))); } else if (option.Value.Equals(ScriptingRuntimeHelpers.True)) { gen.Emit(OpCodes.Ldsfld, True); } else if (option.Value.Equals(ScriptingRuntimeHelpers.False)) { gen.Emit(OpCodes.Ldsfld, False); } gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(Dictionary <string, object>)).GetMethod("Add", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(object)) }), Type.EmptyTypes); } } Label tryStart = gen.BeginExceptionBlock(); // get the ScriptCode assembly... if (config.Embed) { // put the generated DLL into the resources for the stub exe var mem = new MemoryStream(); var rw = new ResourceWriter(mem); rw.AddResource("IPDll." + Path.GetFileNameWithoutExtension(config.Output) + ".dll", File.ReadAllBytes(Path.Combine(config.OutputPath, config.Output) + ".dll")); rw.Generate(); mem.Position = 0; mb.DefineManifestResource("IPDll.resources", mem, ResourceAttributes.Public); File.Delete(Path.Combine(config.OutputPath, config.Output) + ".dll"); // generate code to load the resource gen.Emit(OpCodes.Ldstr, "IPDll"); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes); gen.Emit(OpCodes.Newobj, u.Import(typeof(System.Resources.ResourceManager)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(System.Reflection.Assembly)) })); gen.Emit(OpCodes.Ldstr, "IPDll." + Path.GetFileNameWithoutExtension(config.Output) + ".dll"); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Resources.ResourceManager)).GetMethod("GetObject", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("Load", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])) }), Type.EmptyTypes); } else { // save current working directory gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("get_CurrentDirectory"), Type.EmptyTypes); gen.Emit(OpCodes.Stloc, strVar); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes); gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Reflection.Assembly)).GetMethod("get_Location"), Type.EmptyTypes); gen.Emit(OpCodes.Newobj, u.Import(typeof(System.IO.FileInfo)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)) })); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.FileInfo)).GetMethod("get_Directory"), Type.EmptyTypes); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.DirectoryInfo)).GetMethod("get_FullName"), Type.EmptyTypes); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("set_CurrentDirectory"), Type.EmptyTypes); gen.Emit(OpCodes.Ldstr, config.Output + ".dll"); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.Path)).GetMethod("GetFullPath", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes); // result of GetFullPath stays on the stack during the restore of the // original working directory // restore original working directory gen.Emit(OpCodes.Ldloc, strVar); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("set_CurrentDirectory"), Type.EmptyTypes); // for the LoadFile() call, the full path of the assembly is still is on the stack // as the result from the call to GetFullPath() gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("LoadFile", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes); } // emit module name gen.Emit(OpCodes.Ldstr, "__main__"); // main module name gen.Emit(OpCodes.Ldnull); // no references gen.Emit(OpCodes.Ldc_I4_0); // don't ignore environment variables for engine startup if (config.PythonOptions.Count > 0) { gen.Emit(OpCodes.Ldloc, dictVar); } else { gen.Emit(OpCodes.Ldnull); } // call InitializeModuleEx // (this will also run the script) // and put the return code on the stack gen.EmitCall(OpCodes.Call, u.Import(typeof(PythonOps)).GetMethod("InitializeModuleEx", new IKVM.Reflection.Type[] { u.Import(typeof(System.Reflection.Assembly)), u.Import(typeof(string)), u.Import(typeof(string[])), u.Import(typeof(bool)), u.Import(typeof(Dictionary <string, object>)) }), Type.EmptyTypes); gen.Emit(OpCodes.Stloc, intVar); gen.BeginCatchBlock(u.Import(typeof(Exception))); if (config.Target == PEFileKinds.ConsoleApplication) { gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Exception)).GetMethod("get_Message", Type.EmptyTypes), Type.EmptyTypes); gen.Emit(OpCodes.Stloc, strVar); gen.Emit(OpCodes.Ldstr, config.ErrorMessageFormat); gen.Emit(OpCodes.Ldloc, strVar); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Console)).GetMethod("WriteLine", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes); } else { gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Exception)).GetMethod("get_Message", Type.EmptyTypes), Type.EmptyTypes); gen.Emit(OpCodes.Stloc, strVar); gen.Emit(OpCodes.Ldstr, config.ErrorMessageFormat); gen.Emit(OpCodes.Ldloc, strVar); gen.EmitCall(OpCodes.Call, u.Import(typeof(string)).GetMethod("Format", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes); gen.Emit(OpCodes.Ldstr, "Error"); gen.Emit(OpCodes.Ldc_I4, (int)System.Windows.Forms.MessageBoxButtons.OK); gen.Emit(OpCodes.Ldc_I4, (int)System.Windows.Forms.MessageBoxIcon.Error); gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Windows.Forms.MessageBox)).GetMethod("Show", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)), u.Import(typeof(System.Windows.Forms.MessageBoxButtons)), u.Import(typeof(System.Windows.Forms.MessageBoxIcon)) }), Type.EmptyTypes); gen.Emit(OpCodes.Pop); } gen.Emit(OpCodes.Ldc_I4, -1); // return code is -1 to show failure gen.Emit(OpCodes.Stloc, intVar); gen.EndExceptionBlock(); gen.Emit(OpCodes.Ldloc, intVar); gen.Emit(OpCodes.Ret); tb.CreateType(); ab.SetEntryPoint(mainMethod, config.Target); string fileName = aName.Name.EndsWith(".exe") ? aName.Name : aName.Name + ".exe"; ab.Save(fileName, config.Platform, config.Machine); }
public void ParseArgs(IEnumerable <string> args, List <string> respFiles = null) { foreach (var a in args) { var arg = a.Trim(); if (arg.StartsWith("#")) { continue; } if (arg.StartsWith("/main:")) { MainName = Main = arg.Substring(6).Trim('"'); // only override the target kind if its currently a DLL if (Target == PEFileKinds.Dll) { Target = PEFileKinds.ConsoleApplication; } } else if (arg.StartsWith("/out:")) { Output = arg.Substring(5).Trim('"'); } else if (arg.StartsWith("/target:")) { string tgt = arg.Substring(8).Trim('"'); switch (tgt) { case "exe": Target = PEFileKinds.ConsoleApplication; break; case "winexe": Target = PEFileKinds.WindowApplication; break; default: Target = PEFileKinds.Dll; break; } } else if (arg.StartsWith("/platform:")) { string plat = arg.Substring(10).Trim('"'); switch (plat) { case "x86": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.Required32Bit; Machine = IKVM.Reflection.ImageFileMachine.I386; break; case "x64": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.PE32Plus; Machine = IKVM.Reflection.ImageFileMachine.AMD64; break; default: Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly; Machine = IKVM.Reflection.ImageFileMachine.I386; break; } } else if (arg.StartsWith("/win32icon:")) { Win32Icon = arg.Substring(11).Trim('"'); } else if (arg.StartsWith("/version:")) { Version = arg.Substring(9).Trim('"'); } else if (arg.StartsWith("/errfmt:")) { ErrorMessageFormat = arg.Substring(8); } else if (arg.StartsWith("/embed")) { Embed = true; } else if (arg.StartsWith("/standalone")) { Standalone = true; } else if (arg.StartsWith("/mta")) { UseMta = true; } else if (arg.StartsWith("/file_info")) { string[] items = arg.Substring(10).Split(':'); if (items.Length == 2) { switch (items[0].Trim()) { case "version": FileInfoVersion = new Version(items[1].Trim()); break; case "product": FileInfoProduct = items[1].Trim(); break; case "product_version": FileInfoProductVersion = items[1].Trim(); break; case "company": FileInfoCompany = items[1].Trim(); break; case "copyright": FileInfoCopyright = items[1].Trim(); break; case "trademark": FileInfoTrademark = items[1].Trim(); break; default: ConsoleOps.Warning("Unknown File Information option {0}", arg); break; } } } else if (Array.IndexOf(new string[] { "/?", "-?", "/h", "-h" }, args) >= 0) { ConsoleOps.Usage(true); } else { if (arg.StartsWith("@")) { var respFile = Path.GetFullPath(arg.Substring(1)); if (respFiles == null) { respFiles = new List <string>(); } if (!respFiles.Contains(respFile)) { respFiles.Add(respFile); ParseArgs(File.ReadAllLines(respFile), respFiles); } else { ConsoleOps.Warning("Already parsed response file '{0}'", arg.Substring(1)); } } else { Files.Add(arg); } } } }
public void ParseArgs(IEnumerable <string> args, List <string> respFiles = null) { var helpStrings = new string[] { "/?", "-?", "/h", "-h" }; foreach (var a in args) { var arg = a.Trim(); if (arg.StartsWith("#", StringComparison.Ordinal)) { continue; } if (arg.StartsWith("/main:", StringComparison.Ordinal)) { MainName = Main = arg.Substring(6).Trim('"'); // only override the target kind if its currently a DLL if (Target == PEFileKinds.Dll) { Target = PEFileKinds.ConsoleApplication; } } else if (arg.StartsWith("/out:", StringComparison.Ordinal)) { Output = arg.Substring(5).Trim('"'); } else if (arg.StartsWith("/target:", StringComparison.Ordinal)) { string tgt = arg.Substring(8).Trim('"'); switch (tgt) { case "exe": Target = PEFileKinds.ConsoleApplication; break; case "winexe": Target = PEFileKinds.WindowApplication; break; default: Target = PEFileKinds.Dll; break; } } else if (arg.StartsWith("/platform:", StringComparison.Ordinal)) { string plat = arg.Substring(10).Trim('"'); switch (plat) { case "x86": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.Required32Bit; Machine = IKVM.Reflection.ImageFileMachine.I386; break; case "x64": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.PE32Plus; Machine = IKVM.Reflection.ImageFileMachine.AMD64; break; default: Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly; Machine = IKVM.Reflection.ImageFileMachine.AMD64; break; } } else if (arg.StartsWith("/win32icon:", StringComparison.Ordinal)) { Win32Icon = arg.Substring(11).Trim('"'); } else if (arg.StartsWith("/fileversion:", StringComparison.Ordinal)) { FileVersion = arg.Substring(13).Trim('"'); } else if (arg.StartsWith("/productversion:", StringComparison.Ordinal)) { ProductVersion = arg.Substring(16).Trim('"'); } else if (arg.StartsWith("/productname:", StringComparison.Ordinal)) { ProductName = arg.Substring(13).Trim('"'); } else if (arg.StartsWith("/copyright:", StringComparison.Ordinal)) { Copyright = arg.Substring(11).Trim('"'); } else if (arg.StartsWith("/errfmt:", StringComparison.Ordinal)) { ErrorMessageFormat = arg.Substring(8); } else if (arg.Equals("/embed", StringComparison.Ordinal)) { Embed = true; } else if (arg.Equals("/standalone", StringComparison.Ordinal)) { Standalone = true; } else if (arg.Equals("/mta", StringComparison.Ordinal)) { UseMta = true; } else if (arg.Equals("/sta", StringComparison.Ordinal)) { UseSta = true; } else if (arg.StartsWith("/recurse:", StringComparison.Ordinal)) { string pattern = arg.Substring(9); if (string.IsNullOrWhiteSpace(pattern)) { ConsoleOps.Error(true, "Missing pattern for /recurse option"); } foreach (var f in Directory.EnumerateFiles(Environment.CurrentDirectory, pattern)) { Files.Add(Path.GetFullPath(f)); } } else if (Array.IndexOf(helpStrings, arg) >= 0) { ConsoleOps.Usage(true); } else if (arg.StartsWith("/py:", StringComparison.Ordinal)) { // if you add a parameter that takes a different type then // ScriptingRuntimeHelpers.True/False or int // you need ot also modify Program.cs for standalone generation. string[] pyargs = arg.Substring(4).Trim('"').Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (pyargs[0]) { case "-X:Frames": PythonOptions["Frames"] = ScriptingRuntimeHelpers.True; break; case "-X:FullFrames": PythonOptions["Frames"] = PythonOptions["FullFrames"] = ScriptingRuntimeHelpers.True; break; case "-X:Tracing": PythonOptions["Tracing"] = ScriptingRuntimeHelpers.True; break; case "-X:GCStress": int gcStress; if (!int.TryParse(pyargs[1], out gcStress) || (gcStress <0 || gcStress> GC.MaxGeneration)) { ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be between 0 and {GC.MaxGeneration}."); } PythonOptions["GCStress"] = gcStress; break; case "-X:MaxRecursion": // we need about 6 frames for starting up, so 10 is a nice round number. int limit; if (!int.TryParse(pyargs[1], out limit) || limit < 10) { ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be an integer >= 10."); } PythonOptions["RecursionLimit"] = limit; break; case "-X:EnableProfiler": PythonOptions["EnableProfiler"] = ScriptingRuntimeHelpers.True; break; case "-X:LightweightScopes": PythonOptions["LightweightScopes"] = ScriptingRuntimeHelpers.True; break; case "-X:Debug": PythonOptions["Debug"] = ScriptingRuntimeHelpers.True; break; } } else { if (arg.StartsWith("@", StringComparison.Ordinal)) { var respFile = Path.GetFullPath(arg.Substring(1)); if (respFiles == null) { respFiles = new List <string>(); } if (!respFiles.Contains(respFile)) { respFiles.Add(respFile); ParseArgs(File.ReadAllLines(respFile), respFiles); } else { ConsoleOps.Warning($"Already parsed response file '{arg.Substring(1)}'"); } } else { if (arg.ToLower().EndsWith(".dll", StringComparison.Ordinal)) { DLLs.Add(arg); } else { Files.Add(arg); } } } } }