예제 #1
0
def pinvoke_module():
    domain = AppDomain.CurrentDomain
    name = AssemblyName('pinvoke')
    flag = AssemblyBuilderAccess.Run
    assembly = domain.DefineDynamicAssembly(name, flag)
    module = assembly.DefineDynamicModule('pinvoke')
    return module
예제 #2
0
def GenerateExe(name, targetKind, platform, machine, main_module):
    """generates the stub .EXE file for starting the app"""
    aName = AssemblyName(System.IO.FileInfo(name).Name)
    ab = PythonOps.DefineDynamicAssembly(aName,
                                         AssemblyBuilderAccess.RunAndSave)
    mb = ab.DefineDynamicModule(name, aName.Name + '.exe')
    tb = mb.DefineType('PythonMain', TypeAttributes.Public)
    mainMethod = tb.DefineMethod(
        'Main', MethodAttributes.Public | MethodAttributes.Static, int, ())
    if targetKind == System.Reflection.Emit.PEFileKinds.WindowApplication:
        mainMethod.SetCustomAttribute(
            clr.GetClrType(System.STAThreadAttribute).GetConstructor(()),
            System.Array[System.Byte](()))
    gen = mainMethod.GetILGenerator()

    # get the ScriptCode assembly...
    gen.EmitCall(OpCodes.Call,
                 clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ())
    gen.EmitCall(OpCodes.Call,
                 clr.GetClrType(Assembly).GetMethod("get_CodeBase"), ())
    gen.Emit(OpCodes.Newobj,
             clr.GetClrType(System.Uri).GetConstructor((str, )))
    gen.EmitCall(OpCodes.Call,
                 clr.GetClrType(System.Uri).GetMethod("get_LocalPath"), ())
    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, name + ".dll")
    gen.EmitCall(
        OpCodes.Call,
        clr.GetClrType(System.IO.Path).GetMethod("GetFullPath",
                                                 (clr.GetClrType(str), )), ())
    gen.EmitCall(
        OpCodes.Call,
        clr.GetClrType(System.Reflection.Assembly).GetMethod(
            "LoadFile", (clr.GetClrType(str), )), ())

    # emit module name
    gen.Emit(OpCodes.Ldstr, "__main__")

    gen.Emit(OpCodes.Ldnull)

    # call InitializeModule
    gen.EmitCall(OpCodes.Call,
                 clr.GetClrType(PythonOps).GetMethod("InitializeModule"), ())
    gen.Emit(OpCodes.Ret)

    tb.CreateType()
    ab.SetEntryPoint(mainMethod, targetKind)
    ab.Save(aName.Name + '.exe', platform, machine)
예제 #3
0
 def define_interface(typename, bases):
     for b in bases:
         validate_clr_types(b)
     if not ClrInterface.interface_module_builder:
         name = AssemblyName("interfaces")
         access = AssemblyBuilderAccess.Run
         assembly_builder = ReflectionUtils.DefineDynamicAssembly(name, access)
         ClrInterface.interface_module_builder = assembly_builder.DefineDynamicModule("interfaces")
     attrs = TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract
     return ClrInterface.interface_module_builder.DefineType(typename, attrs, None, bases)
예제 #4
0
파일: reg.py 프로젝트: yanzj/bkt-toolbox
    def load_assembly_attributes(self):
        assembly = Assembly.ReflectionOnlyLoadFrom(self.assembly_path)
        assembly_name = AssemblyName(assembly.FullName)
        assembly_uri = u'file:///' + self.assembly_path.replace(os.path.sep, u'/')

        p = Properties()
        p.full_name = assembly.FullName
        p.version = str(assembly_name.Version)
        p.codebase_uri = assembly_uri
        p.runtime_version = assembly.ImageRuntimeVersion
        self.assembly_properties = p
예제 #5
0
def _create_asm_file(extension, ext_asm_file_name, ext_asm_file_path):
    # check to see if any older assemblies have been loaded for this package
    ext_asm_full_file_name = make_canonical_name(ext_asm_file_name,
                                                 ASSEMBLY_FILE_TYPE)

    # this means that we currently have this package loaded and
    # we're reloading a new version
    is_reloading_pkg = _is_any_ext_asm_loaded(extension)

    # create assembly
    logger.debug('Building assembly for package: {}'.format(extension))
    pyrvt_ver_int_tuple = PYREVIT_VERSION.as_int_tuple()
    win_asm_name = AssemblyName(Name=ext_asm_file_name,
                                Version=Version(pyrvt_ver_int_tuple[0],
                                                pyrvt_ver_int_tuple[1],
                                                pyrvt_ver_int_tuple[2]))
    logger.debug('Generated assembly name for this package: {0}'.format(
        ext_asm_file_name))
    logger.debug(
        'Generated windows assembly name for this package: {0}'.format(
            win_asm_name))
    logger.debug('Generated assembly file name for this package: {0}'.format(
        ext_asm_full_file_name))

    # get assembly builder
    asm_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
        win_asm_name, AssemblyBuilderAccess.RunAndSave,
        op.dirname(ext_asm_file_path))

    # get module builder
    module_builder = asm_builder.DefineDynamicModule(ext_asm_file_name,
                                                     ext_asm_full_file_name)

    # create classes that could be called from any button (shared classes)
    # currently only default availability class is implemented.
    # Default availability class is for resetting buttons back to normal
    # context state (when reloading and after their context
    # has changed during a session).
    make_shared_types(module_builder)

    # create command classes
    for cmd_component in extension.get_all_commands():
        # create command executor class for this command
        logger.debug('Creating types for command: {}'.format(cmd_component))
        make_cmd_types(extension, cmd_component, module_builder)

    # save final assembly
    asm_builder.Save(ext_asm_full_file_name)
    load_asm_file(ext_asm_file_path)

    logger.debug('Executer assembly saved.')
    return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path,
                                 is_reloading_pkg)
예제 #6
0
 def define_interface(typename, bases):
     for b in bases:
         validate_clr_types(b)
     if not ClrInterface.interface_module_builder:
         name = AssemblyName("interfaces")
         access = AssemblyBuilderAccess.Run
         # Workaround for http://ironpython.codeplex.com/WorkItem/View.aspx?WorkItemId=25330
         for i in xrange(1000):
             try:
                 ad = AppDomain.CurrentDomain
                 assembly_builder = ad.DefineDynamicAssembly(name, access)
             except: pass
             else: break
         ClrInterface.interface_module_builder = assembly_builder.DefineDynamicModule("interfaces")
     attrs = TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract
     return ClrInterface.interface_module_builder.DefineType(typename, attrs, None, bases)
예제 #7
0
def compile_parameters(badger_config, badger_dir, dll_path):
    """Compile ValueList parameters and save them to a .gha assembly."""
    # https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.assemblybuilder?view=netframework-4.8
    parameters = badger_config["parameters"]
    base_constructor = clr.GetClrType(HoneyBadgerValueList).GetConstructor(
        Array[Type]([str, str, str, str, str, str]))

    dll_folder = os.path.dirname(dll_path)
    dll_name = os.path.splitext(os.path.basename(dll_path))[0]
    assembly_name = AssemblyName(dll_name)
    assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
        assembly_name, AssemblyBuilderAccess.RunAndSave, dll_folder)
    module_builder = assembly_builder.DefineDynamicModule(
        assembly_name.Name, assembly_name.Name + ".gha")
    for parameter in parameters:
        assert parameter[
            "parameter-type"] == "ValueList", "honey-badger can only produce ValueList parameters"
        keys, values = read_values(badger_dir, parameter["csv"])
        type_builder = module_builder.DefineType(parameter["class-name"],
                                                 TypeAttributes.Public,
                                                 HoneyBadgerValueList)
        constructor_builder = type_builder.DefineConstructor(
            MethodAttributes.Public, CallingConventions.Standard,
            Type.EmptyTypes)
        il_generator = constructor_builder.GetILGenerator()
        il_generator.Emit(OpCodes.Ldarg_0)  # load "this" onto stack
        il_generator.Emit(OpCodes.Ldstr,
                          parameter["name"])  # load constructor args (name)
        il_generator.Emit(
            OpCodes.Ldstr,
            parameter["abbreviation"])  # load constructor args (nickname)
        il_generator.Emit(
            OpCodes.Ldstr,
            parameter["description"])  # load constructor args (description)
        il_generator.Emit(
            OpCodes.Ldstr,
            parameter["category"])  # load constructor args (category)
        il_generator.Emit(
            OpCodes.Ldstr,
            parameter["subcategory"])  # load constructor args (subCategory)
        il_generator.Emit(OpCodes.Ldstr,
                          parameter["id"])  # load constructor args (guid)
        il_generator.Emit(
            OpCodes.Call,
            base_constructor)  # call constructor, consumes args and "this"
        il_generator.Emit(OpCodes.Ret)  # return from constructor

        override_load_value_list(type_builder, keys=keys, values=values)

        if "icon" in parameter:
            # convert icon (a path) to a base64 string
            icon_path = os.path.join(badger_dir, parameter["icon"])
            assert os.path.exists(
                icon_path), "Could not find icon file: {}".format(icon_path)
            override_get_icon_string(type_builder, icon_path)

        type_builder.CreateType()

    # add a GH_AssemblyInfo to the assembly...
    create_gh_assembly_info(badger_config, module_builder)

    assembly_builder.Save(assembly_name.Name + ".gha")
예제 #8
0
파일: pyc.py 프로젝트: mahongquan/ipy_rtf
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)
예제 #9
0
파일: pyc.py 프로젝트: HBDunn/ipybuilder
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")
예제 #10
0
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)