def GenerateExe(config): """generates the stub .EXE file for starting the app""" aName = AssemblyName(System.IO.FileInfo(config.output).Name) if config.file_version is not None: aName.Version = Version(config.file_version) ab = PythonOps.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave) ab.DefineVersionInfoResource(config.file_info_product, config.file_info_product_version, config.file_info_company, config.file_info_copyright, config.file_info_trademark) mb = ab.DefineDynamicModule(config.output, aName.Name + ".exe") tb = mb.DefineType("PythonMain", TypeAttributes.Public) assemblyResolveMethod = None # 3/19/2018 # Copyright 2018 - hdunn. Apache 2.0 licensed. Modified from original. # --- handle dll and StdLib embed ----------- dllNames = [] if config.embed and config.dlls: #not for standalone ? config.dlls = list(set(config.dlls)) opath = System.IO.Path.GetDirectoryName(config.output) for dll in config.dlls: dpath = System.IO.Path.GetFileName(dll) dllNames.append(dpath) lpath = System.IO.Path.Combine(opath,dpath) if '.dll' not in dll: try: print 'Adding to Ref: ' + lpath clr.AddReferenceToFileAndPath(lpath) except Exception as exa: msg = ('File | Filepath: \n {}: ' + 'not a DLL file or does not exist.').format(dll) raise IOError(str(exa) + '\n' + msg) elif '.dll' in dll: try: print 'Adding .dll to Ref: ' + dll clr.AddReferenceToFileAndPath(dll) except Exception as exb: msg = ('File | Filepath: \n {}: ' + 'not a DLL file or does not exist.').format(dll) raise IOError(str(exb) + '\n' + msg) outdir = System.IO.Path.GetDirectoryName(config.output) if config.standalone or config.libembed or config.embed: StdLibOutPath = System.IO.Path.Combine(outdir,'StdLib.dll') clrHasStdLib = False for clrRef in clr.References: if 'StdLib' in str(clrRef): clrHasStdLib = True # error if already so try if System.IO.File.Exists(StdLibOutPath) and not clrHasStdLib: try: clr.AddReferenceToFileAndPath(StdLibOutPath) clrHasStdLib = True except(System.IO.IOException, System.IO.FileLoadException) as exd: if exd.GetType()==System.IO.IOException: msg = ('File | Filepath:\nStdLib.dll or {}:\n ' + 'Not a DLL file or does not exist.') \ .format(config.output + '.dll') print msg elif exd.GetType()==System.IO.FileLoadException: msg = ('File | Filepath: {}\n' + 'Not a clr Loadable file.') \ .format(config.output + '.dll') print msg if not clrHasStdLib: try: clr.AddReference("StdLib.dll") except (System.IO.IOException, System.IO.FileLoadException) as ex: if ex.GetType()==System.IO.IOException: msg = ('File | Filepath:\nStdLib.dll or {}:\n ' + 'Not a DLL file or does not exist.') \ .format(config.output + '.dll') print msg elif ex.GetType()==System.IO.FileLoadException: msg = ('File | Filepath: {}\n' + 'Not a clr Loadable file.') \ .format(config.output + '.dll') print msg print print 'Trying to finish .... - check compiled function, paths and access' print config.embed = True # 3/19/2018,4/3/2018 # Copyright 2018 - hdunn. Apache 2.0 licensed. Modified from original. # ----- handle dll and StdLib embed ----------- embedDict = {} for a in System.AppDomain.CurrentDomain.GetAssemblies(): n = AssemblyName(a.FullName) if not a.IsDynamic and not a.EntryPoint: if config.standalone: if n.Name.StartsWith("IronPython") or \ n.Name in ['Microsoft.Dynamic', 'Microsoft.Scripting']: embedDict[n] = a # hdunn 3/15/2018 any(n.Name in dlln for dlln in dllNames) or \ above if any(n.Name in dlln for dlln in dllNames): embedDict[n] = a if config.libembed and 'StdLib' in n.Name: embedDict[n] = a for name, assem in embedDict.iteritems(): print "\tEmbedding %s %s" % (name.Name, str(name.Version)) print ' path:\n ' + str(assem.Location) if assem.Location: print 'exists' + str(System.IO.File.Exists(assem.Location)) if System.IO.File.Exists(assem.Location): f = System.IO.FileStream(assem.Location, System.IO.FileMode.Open, System.IO.FileAccess.Read) mb.DefineManifestResource("Dll." + name.Name, f, 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, clr.GetClrType(Assembly), (clr.GetClrType(System.Object), clr.GetClrType(System.ResolveEventArgs))) gen = assemblyResolveMethod.GetILGenerator() s = gen.DeclareLocal(clr.GetClrType(System.IO.Stream)) # resource stream gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Stloc, s) d = gen.DeclareLocal(clr.GetClrType(System.Array[System.Byte])) # data buffer gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Ldstr, "Dll.") gen.Emit(OpCodes.Ldarg_1) # The event args gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.ResolveEventArgs).GetMethod("get_Name"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(AssemblyName).GetConstructor((str, ))) gen.EmitCall(OpCodes.Call, clr.GetClrType(AssemblyName).GetMethod("get_Name"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(str).GetMethod("Concat", (str, str)), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("GetManifestResourceStream", (str, )), ()) gen.Emit(OpCodes.Stloc, s) gen.Emit(OpCodes.Ldloc, s) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Newarr, clr.GetClrType(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, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Conv_I4) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("Read", (clr.GetClrType(System.Array[System.Byte]), int, int)), ()) gen.Emit(OpCodes.Pop) gen.Emit(OpCodes.Ldloc, d) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) 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. staticConstructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, System.Type.EmptyTypes) gen = staticConstructor.GetILGenerator() gen.EmitCall(OpCodes.Call, clr.GetClrType(System.AppDomain).GetMethod("get_CurrentDomain"), ()) gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Ldftn, assemblyResolveMethod) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.ResolveEventHandler).GetConstructor((clr.GetClrType(System.Object), clr.GetClrType(System.IntPtr)))) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.AppDomain).GetMethod("add_AssemblyResolve"), ()) gen.Emit(OpCodes.Ret) mainMethod = tb.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, int, ()) if config.target == System.Reflection.Emit.PEFileKinds.WindowApplication and config.mta: mainMethod.SetCustomAttribute(clr.GetClrType(System.MTAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) elif config.target == System.Reflection.Emit.PEFileKinds.WindowApplication: mainMethod.SetCustomAttribute(clr.GetClrType(System.STAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) gen = mainMethod.GetILGenerator() # get the ScriptCode assembly... if config.embed: # put the generated DLL into the resources for the stub exe w = mb.DefineResource("IPDll.resources", "Embedded IronPython Generated DLL") # print 'IPDLL NAME: ' + 'IPDLL.' + config.output # 4/4/2018 Copyright 2018 - hdunn. Apache 2.0 licensed. Modified from original.----- IPDLL NAME strPathRefIPDll = System.IO.DirectoryInfo(config.output).Name #--- 'Changed to: ' + "IPDll." + strPathRefIPDll # comment out System.IO.File.Exists(config.output + ".dll")) # w.AddResource("IPDll." + config.output, System.IO.File.ReadAllBytes(config.output + ".IPDLL")) w.AddResource("IPDll." + strPathRefIPDll, System.IO.File.ReadAllBytes(config.output + ".IPDLL")) #-------------------- # generate code to load the resource gen.Emit(OpCodes.Ldstr, "IPDll") gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.Resources.ResourceManager).GetConstructor((str, clr.GetClrType(Assembly)))) # ---- hdunn dido -------- gen.Emit(OpCodes.Ldstr, "IPDll." + strPathRefIPDll)#strPathRefIPDll)#config.output 4/4 # ------------------ gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Resources.ResourceManager).GetMethod("GetObject", (str, )), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Reflection.Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) if config.verbose: print 'Base embed... completed {}'.format(config.output + ".dll") else: if config.verbose: print 'No embed' # variables for saving original working directory und return code of script wdSave = gen.DeclareLocal(str) # save current working directory gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("get_CurrentDirectory"), ()) gen.Emit(OpCodes.Stloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("get_Location"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.IO.FileInfo).GetConstructor((str, ))) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.FileInfo).GetMethod("get_Directory"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.DirectoryInfo).GetMethod("get_FullName"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) # 4.11.2018 Copyright 2018 - hdunn. Apache 2.0 licensed. Modified from original. strPathRefDll = System.IO.DirectoryInfo(config.output).Name + '.dll' gen.Emit(OpCodes.Ldstr, strPathRefDll) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.Path).GetMethod("GetFullPath", (clr.GetClrType(str), )), ()) # result of GetFullPath stays on the stack during the restore of the # original working directory # restore original working directory gen.Emit(OpCodes.Ldloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) # 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, clr.GetClrType(System.Reflection.Assembly).GetMethod("LoadFile", (clr.GetClrType(str), )), ()) # emit module name if config.verbose: print 'emit main ... ' 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 # call InitializeModule # (this will also run the script) # ------------------------------------- # 3.10.2018 Copyright 2018 - hdunn. Apache 2.0 licensed. Modified from original. Init_Long = None for mi in clr.GetClrType(PythonOps).GetMethods(): if "InitializeModuleEx" in mi.Name and len(mi.GetParameters()) == 4: Init_Long = mi gen.EmitCall(OpCodes.Call, Init_Long, ()) # ------------------------------------- gen.Emit(OpCodes.Ret) tb.CreateType() ab.SetEntryPoint(mainMethod, config.target) ab.Save(aName.Name + ".exe", config.platform, config.machine) if config.verbose: print 'Gen emit ... done' if config.verbose: print "Save as " + aName.Name + ".exe" System.IO.File.Delete(config.output + ".IPDLL")
def GenerateExe(config): """generates the stub .EXE file for starting the app""" aName = AssemblyName(System.IO.FileInfo(config.output).Name) if config.file_version is not None: aName.Version = Version(config.file_version) ab = PythonOps.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave) ab.DefineVersionInfoResource(config.file_info_product, config.file_info_product_version, config.file_info_company, config.file_info_company, config.file_info_trademark) mb = ab.DefineDynamicModule(config.output, aName.Name + ".exe") tb = mb.DefineType("PythonMain", TypeAttributes.Public) assemblyResolveMethod = None if config.standalone: print "Generating stand alone executable" config.embed = True for a in System.AppDomain.CurrentDomain.GetAssemblies(): n = AssemblyName(a.FullName) if not a.IsDynamic and not a.EntryPoint and (n.Name.StartsWith("IronPython") or n.Name in ['Microsoft.Dynamic', 'Microsoft.Scripting']): print "\tEmbedding %s %s" % (n.Name, str(n.Version)) f = System.IO.FileStream(a.Location, System.IO.FileMode.Open, System.IO.FileAccess.Read) mb.DefineManifestResource("Dll." + n.Name, f, 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, clr.GetClrType(Assembly), (clr.GetClrType(System.Object), clr.GetClrType(System.ResolveEventArgs))) gen = assemblyResolveMethod.GetILGenerator() s = gen.DeclareLocal(clr.GetClrType(System.IO.Stream)) # resource stream gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Stloc, s) d = gen.DeclareLocal(clr.GetClrType(System.Array[System.Byte])) # data buffer gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Ldstr, "Dll.") gen.Emit(OpCodes.Ldarg_1) # The event args gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.ResolveEventArgs).GetMethod("get_Name"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(AssemblyName).GetConstructor((str, ))) gen.EmitCall(OpCodes.Call, clr.GetClrType(AssemblyName).GetMethod("get_Name"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(str).GetMethod("Concat", (str, str)), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("GetManifestResourceStream", (str, )), ()) gen.Emit(OpCodes.Stloc, s) gen.Emit(OpCodes.Ldloc, s) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Newarr, clr.GetClrType(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, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Conv_I4) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("Read", (clr.GetClrType(System.Array[System.Byte]), int, int)), ()) gen.Emit(OpCodes.Pop) gen.Emit(OpCodes.Ldloc, d) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) 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. staticConstructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, System.Type.EmptyTypes) gen = staticConstructor.GetILGenerator() gen.EmitCall(OpCodes.Call, clr.GetClrType(System.AppDomain).GetMethod("get_CurrentDomain"), ()) gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Ldftn, assemblyResolveMethod) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.ResolveEventHandler).GetConstructor((clr.GetClrType(System.Object), clr.GetClrType(System.IntPtr)))) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.AppDomain).GetMethod("add_AssemblyResolve"), ()) gen.Emit(OpCodes.Ret) mainMethod = tb.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, int, ()) if config.target == System.Reflection.Emit.PEFileKinds.WindowApplication and config.mta: mainMethod.SetCustomAttribute(clr.GetClrType(System.MTAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) elif config.target == System.Reflection.Emit.PEFileKinds.WindowApplication: mainMethod.SetCustomAttribute(clr.GetClrType(System.STAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) gen = mainMethod.GetILGenerator() # get the ScriptCode assembly... if config.embed: # put the generated DLL into the resources for the stub exe w = mb.DefineResource("IPDll.resources", "Embedded IronPython Generated DLL") w.AddResource("IPDll." + config.output, System.IO.File.ReadAllBytes(config.output + ".dll")) System.IO.File.Delete(config.output + ".dll") # generate code to load the resource gen.Emit(OpCodes.Ldstr, "IPDll") gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.Resources.ResourceManager).GetConstructor((str, clr.GetClrType(Assembly)))) gen.Emit(OpCodes.Ldstr, "IPDll." + config.output) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Resources.ResourceManager).GetMethod("GetObject", (str, )), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Reflection.Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) else: # variables for saving original working directory und return code of script wdSave = gen.DeclareLocal(str) # save current working directory gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("get_CurrentDirectory"), ()) gen.Emit(OpCodes.Stloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("get_Location"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.IO.FileInfo).GetConstructor( (str, ) )) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.FileInfo).GetMethod("get_Directory"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.DirectoryInfo).GetMethod("get_FullName"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) gen.Emit(OpCodes.Ldstr, config.output + ".dll") gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.Path).GetMethod("GetFullPath", (clr.GetClrType(str), )), ()) # result of GetFullPath stays on the stack during the restore of the # original working directory # restore original working directory gen.Emit(OpCodes.Ldloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) # 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, clr.GetClrType(System.Reflection.Assembly).GetMethod("LoadFile", (clr.GetClrType(str), )), ()) # 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 # call InitializeModule # (this will also run the script) ctype=clr.GetClrType(PythonOps) print(dir(ctype)) ops=ctype.GetMethod("InitializeModuleEx") gen.EmitCall(OpCodes.Call,ops, ()) gen.Emit(OpCodes.Ret) tb.CreateType() ab.SetEntryPoint(mainMethod, config.target) ab.Save(aName.Name + ".exe", config.platform, config.machine)
def GenerateExe(config): """generates the stub .EXE file for starting the app""" aName = AssemblyName(System.IO.FileInfo(config.output).Name) if config.file_version is not None: aName.Version = Version(config.file_version) ab = PythonOps.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave) ab.DefineVersionInfoResource(config.file_info_product, config.file_info_product_version, config.file_info_company, config.file_info_company, config.file_info_trademark) mb = ab.DefineDynamicModule(config.output, aName.Name + ".exe") tb = mb.DefineType("PythonMain", TypeAttributes.Public) assemblyResolveMethod = None if config.standalone: print "Generating stand alone executable" config.embed = True for a in System.AppDomain.CurrentDomain.GetAssemblies(): n = AssemblyName(a.FullName) if not a.IsDynamic and not a.EntryPoint and (n.Name.StartsWith("IronPython") or n.Name in ['Microsoft.Dynamic', 'Microsoft.Scripting']): print "\tEmbedding %s %s" % (n.Name, str(n.Version)) f = System.IO.FileStream(a.Location, System.IO.FileMode.Open, System.IO.FileAccess.Read) mb.DefineManifestResource("Dll." + n.Name, f, 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, clr.GetClrType(Assembly), (clr.GetClrType(System.Object), clr.GetClrType(System.ResolveEventArgs))) gen = assemblyResolveMethod.GetILGenerator() s = gen.DeclareLocal(clr.GetClrType(System.IO.Stream)) # resource stream gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Stloc, s) d = gen.DeclareLocal(clr.GetClrType(System.Array[System.Byte])) # data buffer gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Ldstr, "Dll.") gen.Emit(OpCodes.Ldarg_1) # The event args gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.ResolveEventArgs).GetMethod("get_Name"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(AssemblyName).GetConstructor((str, ))) gen.EmitCall(OpCodes.Call, clr.GetClrType(AssemblyName).GetMethod("get_Name"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(str).GetMethod("Concat", (str, str)), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("GetManifestResourceStream", (str, )), ()) gen.Emit(OpCodes.Stloc, s) gen.Emit(OpCodes.Ldloc, s) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Newarr, clr.GetClrType(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, clr.GetClrType(System.IO.Stream).GetMethod("get_Length"), ()) gen.Emit(OpCodes.Conv_I4) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.IO.Stream).GetMethod("Read", (clr.GetClrType(System.Array[System.Byte]), int, int)), ()) gen.Emit(OpCodes.Pop) gen.Emit(OpCodes.Ldloc, d) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) 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. staticConstructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, System.Type.EmptyTypes) gen = staticConstructor.GetILGenerator() gen.EmitCall(OpCodes.Call, clr.GetClrType(System.AppDomain).GetMethod("get_CurrentDomain"), ()) gen.Emit(OpCodes.Ldnull) gen.Emit(OpCodes.Ldftn, assemblyResolveMethod) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.ResolveEventHandler).GetConstructor((clr.GetClrType(System.Object), clr.GetClrType(System.IntPtr)))) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(System.AppDomain).GetMethod("add_AssemblyResolve"), ()) gen.Emit(OpCodes.Ret) mainMethod = tb.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, int, ()) if config.target == System.Reflection.Emit.PEFileKinds.WindowApplication and config.mta: mainMethod.SetCustomAttribute(clr.GetClrType(System.MTAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) elif config.target == System.Reflection.Emit.PEFileKinds.WindowApplication: mainMethod.SetCustomAttribute(clr.GetClrType(System.STAThreadAttribute).GetConstructor(()), System.Array[System.Byte](())) gen = mainMethod.GetILGenerator() # get the ScriptCode assembly... if config.embed: # put the generated DLL into the resources for the stub exe w = mb.DefineResource("IPDll.resources", "Embedded IronPython Generated DLL") w.AddResource("IPDll." + config.output, System.IO.File.ReadAllBytes(config.output + ".dll")) System.IO.File.Delete(config.output + ".dll") # generate code to load the resource gen.Emit(OpCodes.Ldstr, "IPDll") gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.Resources.ResourceManager).GetConstructor((str, clr.GetClrType(Assembly)))) gen.Emit(OpCodes.Ldstr, "IPDll." + config.output) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Resources.ResourceManager).GetMethod("GetObject", (str, )), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Reflection.Assembly).GetMethod("Load", (clr.GetClrType(System.Array[System.Byte]), )), ()) else: # variables for saving original working directory und return code of script wdSave = gen.DeclareLocal(str) # save current working directory gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("get_CurrentDirectory"), ()) gen.Emit(OpCodes.Stloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ()) gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("get_Location"), ()) gen.Emit(OpCodes.Newobj, clr.GetClrType(System.IO.FileInfo).GetConstructor( (str, ) )) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.FileInfo).GetMethod("get_Directory"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.DirectoryInfo).GetMethod("get_FullName"), ()) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) gen.Emit(OpCodes.Ldstr, config.output + ".dll") gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.Path).GetMethod("GetFullPath", (clr.GetClrType(str), )), ()) # result of GetFullPath stays on the stack during the restore of the # original working directory # restore original working directory gen.Emit(OpCodes.Ldloc, wdSave) gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ()) # 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, clr.GetClrType(System.Reflection.Assembly).GetMethod("LoadFile", (clr.GetClrType(str), )), ()) # 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 # call InitializeModule # (this will also run the script) gen.EmitCall(OpCodes.Call, clr.GetClrType(PythonOps).GetMethod("InitializeModuleEx"), ()) gen.Emit(OpCodes.Ret) tb.CreateType() ab.SetEntryPoint(mainMethod, config.target) ab.Save(aName.Name + ".exe", config.platform, config.machine)