IronPython:使用pyc.py编译的EXE无法导入模块“os”

时间:2011-06-01 02:57:09

标签: python ironpython

我有一个简单的IronPython脚本:

# Foo.py
import os

def main():
    print( "Hello" )

if "__main__" == __name__:
    main()

运行正常并打印 Hello 如果我用IronPython运行它:

ipy Foo.py

按照 IronPython - how to compile exe 中的说明,我使用以下命令将此IronPython脚本编译为EXE:

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

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

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?

(请注意,这与问题 IronPython cannot import module os 不同,因为如果我使用ipy.exe运行,脚本可以正常工作。)

2 个答案:

答案 0 :(得分:24)

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

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

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安装。如果要分发给未安装Python的人员,则必须这样做。只需确保在创建安装程序时包含必要的DLL。

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

答案 1 :(得分:7)

我知道这已经回答了很长时间但是我的工作时间仍然花了很多时间。我指出了5个错误消息,其中存在此​​导入问题。这是我必须做的才能使我的exe工作:

1)在deploy文件夹(IronPython.dll,IronPython.Modules.dll等)中包含所有IronPython dll。

2)包括deploye文件夹中标准库的dll

3)exe所在的路径应该没有空格

(这: C:\ User1 \ MyDocuments \ My Folder \ deployFolder

应该更改为例如: C:\用户1 \我的文档\ MyFolder文件\ deployFolder)

4)你的操作系统可能会阻止你的exe文件使用的一个dll并给你一个“loadFromRemoteResource comutator error blablabla”。要解决这个问题,你需要右键单击dll,然后在窗口的最后一行按“unblock”。

5)最后不要忘记将pyc给出的dll文件包含在你的exe文件中(同名,扩展名只有区别)

如果您需要,我写了一篇文章,其中包含更多详细信息:http://thesesergio.wordpress.com/2013/09/11/how-to-generate-and-use-a-exe-that-uses-net-dlls-with-ironpython-pyc-py/