将IronPython编译为使用标准库的exe文件

2 投票
1 回答
1912 浏览
提问于 2025-04-18 08:44

在我的IronPython脚本中,我使用了一些标准库模块,比如ConfigParser、logging和JSON。

然后我用pyc.py来创建一个可执行文件。起初我遇到了一些问题,具体来说就是'...ImportException: no module named ...',因为这些模块没有被包含在生成的exe和相关的dll文件中。

于是我参考了这里的一个解决方案:IronPython: EXE compiled using pyc.py cannot import module "os",这个方法大部分是有效的。

举个例子,导入'ConfigParser'是可以成功的,因为在IronPython的'Lib'文件夹中,它作为一个模块存在,文件名是'ConfigParser.py'。不过,我在使用JSONlogging时仍然遇到麻烦,因为它们在各自的文件夹里(可能是包?)。

我感觉自己可能只是遗漏了一些简单的东西,可能还需要多了解一下Python模块以及它们的实际工作原理,但我不太确定该关注什么。希望能得到一些帮助。

谢谢!

编辑:

我还不能回答自己的问题,所以就把这个留在这里。

我以一种很“hacky”的方式让它工作了。肯定还有其他更干净的解决方案我没找到(pyc.py中可能有某个选项?)

这是我做的事情:

1) 根据上面的链接生成了StdLib.dll文件(IronPython: EXE compiled using pyc.py cannot import module "os")。这个文件缺少标准库的包。

2) 使用SharpDevelop编译那些没有包含在上面dll中的标准库包,具体方法可以参考这里:http://community.sharpdevelop.net/blogs/mattward/archive/2010/03/16/CompilingPythonPackagesWithIronPython.aspx

3) 用SharpDevelop构建我的程序,并将所有引用连接在一起。 - 引用步骤2中生成的dll - 引用步骤1中生成的StdLib.dll

再次强调,肯定还有更好的解决方案。

1 个回答

1

我找到两种方法来编译标准库的Python包:

第一种方法:单独编译每个包成dll文件

使用pyc.py,运行类似下面的命令(这个例子编译的是logging包):

ipy pyc.py ".\Lib\logging\__init__.py" ".\Lib\logging\config.py" ".\Lib\logging\handlers.py" /target:dll /out:logging

这会生成一个logging.dll文件,你可以像这样使用它:

import clr
clr.AddReference('StdLib') #from the compilation of non-package std libraries


clr.AddReference('logging')
import logging

**注意:这假设你已经运行了来自IronPython: 使用pyc.py编译的EXE无法导入模块"os"的解决方案来创建StdLib.dll

第二种方法:修改生成StdLib.dll的编译脚本

我修改了这一行:

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

改成这样:

#Build StdLib.DLL
gb1 = glob.glob(r".\Lib\*.py")
gb2 = glob.glob(r".\Lib\*\*.py")
gb3 = glob.glob(r".\Lib\*\*\*.py")
gb = list(set(gb1 + gb2 + gb3))
gb.append("/out:StdLib")

这样就包括了Lib目录中的子文件夹,而原来的正则表达式只包含了模块(没有子文件夹)。现在像xmljsonlogging等包都被包含进StdLib.dll里了。

撰写回答