构建 pyinstaller 可执行文件时我可以控制架构(32 位还是 64 位)吗?
简短问题
在构建 pyinstaller 可执行文件时,有什么方法可以控制/保证架构(32 位与 64 位)?
背景
我从 py2exe 迁移到 pyinstaller,因为缺乏 64 位支持以及许多我很难处理的小问题。因此,就这一点而言,我宁愿不回到它。我使用 Python 2.7 64 位开发了两个应用程序,在 32 位机器上运行时遇到性能问题。
第一个是简单的 wxPython GUI(版本 2.9),连接到 USB 驱动程序的 Windows DLL 文件。这个在 32 位上运行似乎相当“安全”,因为没有任何模块是 64 位的。然而,当该应用程序在 32 位 Windows XP 上运行时,与 USB 设备通信时会出现严重的性能问题。
第二个应用程序要大得多,由于担心架构问题,我还没有尝试构建和运行。该应用程序使用了许多仅 64 位的模块(其中一个是 psycopg2)。如果它不可能作为 32 位可执行文件运行,我不想尝试构建它。
当前想法
我觉得通过在 32 位模式下强制运行 Python 来运行 build.py 是可能的(如果模块有 32 位支持)。这有什么意义吗?
更新
我在构建的第一个程序上取得了一些突破。事实证明,性能问题完全取决于两台机器的速度。我的开发机器有足够的电量来足够快地轮询 USB 设备,而慢得多的测试平台 (Windows XP) 却没有。
我通过修改轮询 USB 端口的方式解决了这个问题。现在这个问题已经解决了,我可以在两个系统上运行该exe了。尝试将可执行文件构建为单个文件时出现了一个新问题。当运行 pyinstaller 的 Build.py 时,它会提取应用程序运行所需的所有必需 DLL。起初这似乎工作得很好,但是当我尝试运行在 Windows 7 64 位上构建的单个 exe 时,它无法在 Windows XP 上运行,因为 USB 加密狗的 DLL 未被识别为有效的 DLL。
为了让单个 exe 在两个系统上运行,我首先尝试从 .spec 文件(似乎是一个 python 脚本)中删除 DLL。这很方便,因为我可以在构建命令之前使用普通的 python 列表修饰符修改包含列表。我的希望是,如果在 exe 的临时目录中找不到 DLL,它会在系统 PATH 中找到它。虽然这种方法可能有效,但我无法让它在不引发大量错误的情况下运行。
我的第二次尝试是在 Windows XP 计算机上构建应用程序(保留嵌入的 DLL),希望 Win XP DLL 能够在 Windows 7 中运行。成功!这个配置效果很好;但是我坚信这不是最好的解决方案,因为它仅依赖于在较新操作系统上运行的较旧 DLL。
Short Question
Is there any way to control / guarantee the architecture (32bit vs 64bit) when building a pyinstaller executable?
Background
I migrated from py2exe to pyinstaller because of the lack of 64bit support along with a host of small things that I am having a hard time looking past. So on that note, I would prefer not to go back to it. I have developed two applications using Python 2.7 64bit and am having performance issues when running on them 32 bit machines.
The first is a simple wxPython GUI (version 2.9) and connects to a windows DLL file for a USB driver. This one seems pretty "safe" to run as 32 bit because there are no modules which are 64bit only. However this application when running on 32bit Windows XP has horrible performance issues when talking to the USB device.
The second application is much larger and I have not attempted to build and run yet because of the fear of architecture issues. This application has a number 64bit only modules (psycopg2 for one) used in it. I would like to stay away from trying to build this if it impossible to run as a 32bit executable.
Current Thoughts
I feel that this might be possible (if the modules have 32bit support) by running the build.py with Python forced in 32bit mode. Does this make any sense?
Update
I had several breakthroughs on the first program I was building. It turns out the performance issues was solely based on the speed of the two machines. My dev machine had enough power to poll the USB device fast enough and the much slower test platform (Windows XP) did not.
I fixed this issue by modifying the way I polled the USB port. Now that this was fixed, I could run the exe on both systems. A new problem had come up when trying to build the executable as a single file. When running pyinstaller's Build.py, it pulls in all of the required DLL's the app needs to run. This seemed to work great at first, but when I tried to run the single exe that I built on Windows 7 64bit, it would not run on Windows XP because the USB dongle's DLL was not recognized as a valid DLL.
In order to get the single exe to run on both systems, I first tried to remove the DLL from the .spec file (which appears to be a python script). It was convenient because I was able to modify the list of includes prior to the build command with ordinary python list modifiers. My hope was that if the DLL was not found in the exe's temp directory it would find it on the system PATH. While this approach might work, I could not get it to run without throwing lots of errors.
My second attempt was to build the application on the Windows XP machine (leaving the DLL embedded) in hope that the Win XP DLL would work in Windows 7. Success! This configuration works well; however I do strongly believe that this not the best solution as it depends solely on the older DLL running on a newer OS.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Pyinstaller 会根据您用来构建它的 python 生成一个二进制文件。因此,据我所知,如果您使用 python 2.7 64 位,则不可能生成 32 位可执行文件。这是因为 Pyinstaller 归档了所有模块及其依赖项(dll、pyds 等),由于 python 安装,这些模块及其依赖项是 64 位的。
正如已经说过的,由于交叉兼容性问题,构建 32 位二进制文件更好。
也许您可以详细说明您的问题。
Pyinstaller produces a binary depending from the python you used to build it. So if you use python 2.7 64 bit it is not possible, as far as I know, to produce a 32 bit executable. This is because Pyinstaller archives all modules and their dependencies (dlls, pyds etc..) which are 64 bit due to the python install.
As already said it is better, because of cross compatibility issues, to build 32-bit binaries.
Probably you can specify more your question.
如果您正在构建一个应用程序并且它在 32 位 Windows 上运行良好,则无需创建 64 位版本。只需创建一个 32 位版本并在两种体系结构上运行它即可。 WOW64 的用途是什么?
如果您需要使用仅 64 位的库或功能,只需构建 64 位版本。如果功能仅是 64 位,则构建 32 位版本是没有意义的。
同时构建 64 位和 32 位版本的唯一原因是利用 64 位 Windows 增加的地址空间。即,如果您打算分配超过 1 或 2 GB 的内存。一个示例可能是图像编辑应用程序或数据操作应用程序。然后,您可以在平台的限制内在 32 位平台上运行,但可以在 64 位平台上编辑更大的图像或更大量的数据。
IOW,对于您的情况,请遵循@Velociraptors 的建议,如果您正在构建 32 位 exe,则构建 32 位 python。
If you are building an application and it runs fine on 32-bit Windows, there is no need to create a 64-bit version. Just create a 32-bit version and run it on both architectures. What is what WOW64 is for.
If you need to use a library or feature which is 64-bit only, just build a 64-bit version. There is no point in building a 32-bit version if the feature is 64-bit only.
The only reason to build a 64-bit and 32-bit version both, is to take advantage of increased address space of 64-bit windows. I.e. if you intend to allocate more than 1 or 2 GB of memory. An example might be an image editing application, or a data manipulation application. Then you can run on 32-bit platforms within the constraints of the platform but edit larger images or larger quantities of data on 64-bit platforms.
IOW, for your case follow the suggestion of @Velociraptors and build in 32-bit python if you are building a 32-bit exe.
如果您想在 64 位系统上构建 32 位应用程序并且仅安装了 64 位版本的 Python,则还必须安装 32 位版本的 Python。然后,您必须将 pyinstaller 安装到该 32 位 Python 版本,如下所示:
之后您可以运行 32 位版本的 pyinstaller,从而构建一个 32 位应用程序,如下所示:
在 Windows 10 上,pyinstaller。 exe 位于
C:\Users\<用户>\AppData\Local\Programs\Python\Python<版本>-32\Scripts\pyinstaller.exe
。如您所见,您想要构建的应用程序的体系结构取决于您将用于构建该应用程序的 Python 和 pyinstaller 版本。例如,如果系统上安装了 Python 2.x 版本,您还可以通过这种方式构建应用程序。
If you want to build a 32-bit application on a 64-bit system and hav only a 64-bit version of Python installed, you have to install also a 32-bit version of Python. Then you have to instal pyinstaller to that 32-bit Python version as follows:
After that you can run the 32-bit version of pyinstaller, and thus build a 32-bit application, like this:
On Windows 10,
pyinstaller.exe
is located atC:\Users\<user>\AppData\Local\Programs\Python\Python<version>-32\Scripts\pyinstaller.exe
.As you can see, the architecture of the application you want to build depends on the Python and pyinstaller versions which you are going to use to build that application. This way you can also, for instance, build an application from a Python version 2.x if you have it installed on the system.
将 pyinstaller 安装到该 32 位 Python 版本:
通过创建文件 my_installer.py 从 Python 代码运行 PyInstaller:
运行 my_installer.py:
Install pyinstaller to that 32-bit Python version:
Run PyInstaller from Python code by creating the file my_installer.py:
Run my_installer.py: