最佳的方法是如何为部署打包IronPython应用程序?经过搜寻网络,我找到了最好的方法(也是我目前正在使用的方法)是使用clr.CompileModules()
将整个项目的.py文件粘合在一起成为一个.dll文件,然后只需要一个单独的run.py
文件来运行该.dll文件即可:
import clr
clr.AddReference('compiledapp.dll')
import app
这仍然不够理想,因为这意味着我必须:
- 分发三个文件(.dll文件、.xaml文件和run.py启动器)
- 在主机上安装IronPython
理想情况下,我希望能够拥有一个单独的.exe文件,并将.xaml文件合并到其中(我读到C#应用程序将XAML编译为BAML并将其合并到可执行文件中),而不需要安装IronPython即可运行。这至少有一半可能吗?(如果exe文件需要一些额外的.DLL文件或其他东西,那也没关系。重要的是它是以.exe形式存在的。)
一些澄清的编辑:我已经尝试过pyc.py,但它似乎没有意识到我的项目不仅仅是app.py。它生成的exe文件大小表明它只是在“编译”app.py而没有将任何其他文件包含在exe文件中。那么,如何告诉它编译我项目中的每个文件呢? 为了帮助可视化,这里是我项目的解决方案资源管理器窗口的截图。
编辑II:看来唯一的方法是使用
pyc.py
并将每个文件作为参数传递。我对此方法有两个问题:
- 我怎么可能处理这么长的命令行?一个命令中最多只能有256个字符。
- pyc.py如何知道要保留包/文件夹结构?如上面我的项目截图所示,我的编译程序如何知道访问子文件夹中的模块,例如访问DT\Device? 层次结构是否在dll中被“保留”?
编辑III:由于通过命令行传递70个文件名给pyc.py
将会很难处理,并且为了更优雅地解决构建IPy项目的问题,我决定增强pyc.py
。
我添加了一些代码,通过/pyproj:
参数读取一个.pyproj
文件,解析XML并从中获取项目中使用的py文件列表。这一步已经运作得非常好了;然而,生成的可执行文件似乎无法访问作为我的项目一部分的python子包(子文件夹)。我的带有.pyproj
读取支持补丁的pyc.py
版本可以在这里找到:http://pastebin.com/FgXbZY29
当在我的项目上运行这个新的pyc.py
时,输出如下:
c:\Projects\GenScheme\GenScheme>"c:\Program Files (x86)\IronPython 2.7\ipy.exe"
pyc.py /pyproj:GenScheme.pyproj /out:App /main:app.py /target:exe
Input Files:
c:\Projects\GenScheme\GenScheme\__init__.py
c:\Projects\GenScheme\GenScheme\Agent.py
c:\Projects\GenScheme\GenScheme\AIDisplay.py
c:\Projects\GenScheme\GenScheme\app.py
c:\Projects\GenScheme\GenScheme\BaseDevice.py
c:\Projects\GenScheme\GenScheme\BaseManager.py
c:\Projects\GenScheme\GenScheme\BaseSubSystem.py
c:\Projects\GenScheme\GenScheme\ControlSchemes.py
c:\Projects\GenScheme\GenScheme\Cu64\__init__.py
c:\Projects\GenScheme\GenScheme\Cu64\agent.py
c:\Projects\GenScheme\GenScheme\Cu64\aidisplays.py
c:\Projects\GenScheme\GenScheme\Cu64\devmapper.py
c:\Projects\GenScheme\GenScheme\Cu64\timedprocess.py
c:\Projects\GenScheme\GenScheme\Cu64\ui.py
c:\Projects\GenScheme\GenScheme\decorators.py
c:\Projects\GenScheme\GenScheme\DeviceMapper.py
c:\Projects\GenScheme\GenScheme\DT\__init__.py
c:\Projects\GenScheme\GenScheme\DT\Device.py
c:\Projects\GenScheme\GenScheme\DT\Manager.py
c:\Projects\GenScheme\GenScheme\DT\SubSystem.py
c:\Projects\GenScheme\GenScheme\excepts.py
c:\Projects\GenScheme\GenScheme\FindName.py
c:\Projects\GenScheme\GenScheme\GenScheme.py
c:\Projects\GenScheme\GenScheme\PMX\__init__.py
c:\Projects\GenScheme\GenScheme\PMX\Device.py
c:\Projects\GenScheme\GenScheme\PMX\Manager.py
c:\Projects\GenScheme\GenScheme\PMX\SubSystem.py
c:\Projects\GenScheme\GenScheme\pyevent.py
c:\Projects\GenScheme\GenScheme\Scheme.py
c:\Projects\GenScheme\GenScheme\Simulated\__init__.py
c:\Projects\GenScheme\GenScheme\Simulated\Device.py
c:\Projects\GenScheme\GenScheme\Simulated\SubSystem.py
c:\Projects\GenScheme\GenScheme\speech.py
c:\Projects\GenScheme\GenScheme\stdoutWriter.py
c:\Projects\GenScheme\GenScheme\Step.py
c:\Projects\GenScheme\GenScheme\TimedProcess.py
c:\Projects\GenScheme\GenScheme\UI.py
c:\Projects\GenScheme\GenScheme\VirtualSubSystem.py
c:\Projects\GenScheme\GenScheme\Waddle.py
Output:
App
Target:
ConsoleApplication
Platform:
ILOnly
Machine:
I386
Compiling...
Saved to App
所以它正确地读取了.pyproj
文件列表...太好了!但运行exe文件给了我这个:
Unhandled Exception: IronPython.Runtime.Exceptions.ImportException:
No module named Cu64.ui
因此,尽管
Cu64\ui.py
显然已包含在编译中,但运行时exe找不到它。这就是我在上一次编辑中第2点所担心的。如何保留项目的软件包层次结构?也许需要单独编译每个软件包?我将为此问题延长悬赏时间。最终,我希望我们能够获得一个工作的pyc.py,它可以读取pyproj文件并在一步中生成可工作的exe。然后,也许可以提交给IronPython的codeplex以包含在下一个版本中... ;]
__init__.py
来识别它们,这与 Python 包的通常做法相同。 - Lukas Cenovskypyc.py
使用clr.CompileModules
,可以很好地处理包。所以只需使用 pyc.py 就可以了,应该能正常工作;-) - Lukas Cenovsky