IronPython:使用pyc.py编译的EXE无法导入模块"os". [英] IronPython: EXE compiled using pyc.py cannot import module "os"

查看:87
本文介绍了IronPython:使用pyc.py编译的EXE无法导入模块"os".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的IronPython脚本:

I have a simple IronPython script:

# Foo.py
import os

def main():
    print( "Hello" )

if "__main__" == __name__:
    main()

如果我使用IronPython如下运行它,它将运行良好并显示 Hello :

It runs fine and prints Hello if I run it with IronPython as:

ipy Foo.py

按照 IronPython中给出的说明进行操作-如何编译exe ,我使用以下命令将此IronPython脚本编译为EXE:

Following the instructions given in IronPython - how to compile exe, I compiled this IronPython script to a EXE using:

ipy pyc.py /main:Foo.py /target:exe

执行Foo.exe会出现此错误:

Executing Foo.exe gives this error:

Unhandled Exception: IronPython.Runtime.Exceptions.ImportException: No module named os
   at Microsoft.Scripting.Runtime.LightExceptions.CheckAndThrow(Object value)
   at DLRCachedCode.__main__$1(CodeContext $globalContext, FunctionCode $functionCode)
   at IronPython.Compiler.OnDiskScriptCode.Run()
   at IronPython.Compiler.OnDiskScriptCode.Run(Scope scope)
   at IronPython.Runtime.PythonContext.InitializeModule(String fileName, ModuleContext moduleContext, ScriptCode scriptC
ode, ModuleOptions options)

为什么找不到模块"os"?我该如何解决这个问题,以便获得可以正常运行的EXE?

Why cannot module "os" be found? How do I fix this, so I can get a working EXE?

(请注意,这与问题 ="a href =" https://stackoverflow.com/questions/3904374> IronPython无法导入模块os 不同,因为脚本可以正常工作如果我用ipy.exe运行,就可以了.)

(Note that this is different from the question IronPython cannot import module os since the script works fine if I run with ipy.exe.)

推荐答案

构建可以分发的Ironpython EXE有点棘手-尤其是在使用标准库的元素时.我的典型解决方案如下:

Building an Ironpython EXE that you can distribute is a bit tricky - especially if you are using elements of the standard library. My typical solution is the following:

我将需要的所有stdlib模块复制到一个文件夹中(通常都是为了完整性),并使用此脚本来构建我的exe.在此示例中,我有两个文件 FredMain.py FredSOAP.py ,它们被编译成一个名为 Fred_Download_Tool

I copy all of the stdlib modules I need into a folder (usually all of them just for completeness) and use this script to build my exe. In this example I have two files FredMain.py and FredSOAP.py that get compiled into an EXE called Fred_Download_Tool

import sys
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib')
sys.path.append(r'C:\Program Files\IronPython 2.7')
import clr

clr.AddReference('IronPython')
clr.AddReference('IronPython.Modules')
clr.AddReference('Microsoft.Scripting.Metadata')
clr.AddReference('Microsoft.Scripting')
clr.AddReference('Microsoft.Dynamic')
clr.AddReference('mscorlib')
clr.AddReference('System')
clr.AddReference('System.Data')

#
# adapted from os-path-walk-example-3.py

import os, glob
import fnmatch
import pyc

def doscopy(filename1):
    print filename1
    os.system ("copy %s .\\bin\Debug\%s" % (filename1, filename1))

class GlobDirectoryWalker:
    # a forward iterator that traverses a directory tree

    def __init__(self, directory, pattern="*"):
        self.stack = [directory]
        self.pattern = pattern
        self.files = []
        self.index = 0

    def __getitem__(self, index):
        while 1:
            try:
                file = self.files[self.index]
                self.index = self.index + 1
            except IndexError:
                # pop next directory from stack
                self.directory = self.stack.pop()
                self.files = os.listdir(self.directory)
                self.index = 0
            else:
                # got a filename
                fullname = os.path.join(self.directory, file)
                if os.path.isdir(fullname) and not os.path.islink(fullname) and fullname[-4:]<>'.svn':
                    self.stack.append(fullname)
                if fnmatch.fnmatch(file, self.pattern):
                    return fullname

#Build StdLib.DLL
gb = glob.glob(r".\Lib\*.py")
gb.append("/out:StdLib")    

#print ["/target:dll",]+gb

pyc.Main(["/target:dll"]+gb)

#Build EXE
gb=["/main:FredMain.py","FredSOAP.py","/target:exe","/out:Fred_Download_Tool"]
pyc.Main(gb)


#CopyFiles to Release Directory
doscopy("StdLib.dll")
doscopy("Fred_Download_Tool.exe")
doscopy("Fred_Download_.dll")


#Copy DLLs to Release Directory
fl = ["IronPython.dll","IronPython.Modules.dll","Microsoft.Dynamic.dll","Microsoft.Scripting.Debugging.dll","Microsoft.Scripting.dll","Microsoft.Scripting.ExtensionAttribute.dll","Microsoft.Scripting.Core.dll"]
for f in fl:

doscopy(f)

在准备编译时,在脚本中添加以下内容.这允许程序使用我的DLL中的标准模块,而不是Python Install.如果要分发给未安装Python的人,这是必需的.只需确保在创建安装程序时包括必要的DLL.

In my scripts I add the following when I am ready to compile. This allows the program to use the Standard Modules from my DLL instead of the Python Install. This is necessary if you want to distribute to people without Python installed. Just make sure you include the necessary DLL's when you create your installer.

#References to created DLL of python modules
clr.AddReference('StdLib')

这篇关于IronPython:使用pyc.py编译的EXE无法导入模块"os".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆