我正在为 Windows 7 的 Python 应用程序开发 Inno Setup 安装程序,我有以下要求:
- 该应用程序不应向安装目录写入任何内容
- 它应该能够使用 .pyc 文件
- 该应用程序不需要特定的 Python 版本,因此我不能只将一组 .pyc 文件添加到安装程序
有推荐的处理方法吗?就像给用户一种(重新)生成 .pyc 文件的方法?或者 .pyc 文件的启动时间较短通常不值得担心?
我正在为 Windows 7 的 Python 应用程序开发 Inno Setup 安装程序,我有以下要求:
有推荐的处理方法吗?就像给用户一种(重新)生成 .pyc 文件的方法?或者 .pyc 文件的启动时间较短通常不值得担心?
重新阅读原始问题,有一个更简单的答案可能符合您的要求。
我对 Inno 了解不多,但大多数安装程序都为您提供了一种在复制后步骤中运行任意命令的方法。
因此,您可以在安装时使用它为您python -m compileall
创建.pyc
文件——同时您仍然拥有提升的权限,因此 UAC 没有问题。
实际上,如果您查看 .pywin32
以及作为安装程序包提供的各种其他 Python 包,它们正是这样做的。这是将库安装到用户的 Python 安装中的惯用做法,所以我不明白为什么安装使用用户的 Python 安装的可执行文件被认为是不合理的。
当然,如果用户后来决定卸载 Python 2.6 并安装 2.7,您的.pyc
文件将被冲洗掉……但从您的描述来看,听起来您的整个程序无论如何都会被冲洗掉,而为用户推荐的解决方案可能是卸载并无论如何都要重新安装,对吗?
如果您还没有阅读PEP 3147,那可能会回答您的问题。
我不是指该 PEP 中描述并从 Python 3.2 开始实施的解决方案。如果您的“多个 Python 版本”仅表示“3.2、3.3 和未来的 3.x”,那就太好了。或者即使它的意思是“2.6+ 和 3.1+,但我只关心 3.2 和 3.3,所以如果我没有得到其他的 pyc 加速也没关系”。
但是当我问你支持的版本时,你说“2.7”,这意味着你不能依靠 PEP 3147 来解决你的问题。
幸运的是,PEP 充满了对解决问题的早期尝试的讨论,以及每个问题的陷阱,并且应该有足够的内容来弄清楚选项是什么以及如何实施它们。
一个问题是 PEP 非常以 linux 为中心——主要是因为过去主要是 linux 发行版试图解决这个问题。(Apple 也这样做了,但他们的解决方案(a)几乎可以工作,并且(b)与整个 Mac 特定的“框架”紧密耦合,所以它们大多被忽略了......)
因此,它在很大程度上留下了“我应该将 .pyc 文件放在 Windows 的什么位置?”的问题。
最好的选择可能是用户本地应用程序数据目录下的特定于应用程序的目录。如果您需要 Vista 或更高版本,请参阅已知文件夹,如果不能,请参阅CSIDL。无论哪种方式,您都在寻找 FOLDERID_LocalAppData 或 CSIDL_LOCAL_APPDATA,即:
用作本地(非漫游)应用程序的数据存储库的文件系统目录。一个典型的路径是
C:\Documents and Settings\username\Local Settings\Application Data
。
关键是它是应用程序存储数据的地方,这些数据对于每个用户(以及在该用户的配置文件目录中)以及用户的漫游配置文件可能最终出现的每台机器都是分开的,这意味着您可以安全地把东西放在那里并知道用户有权在没有 UAC 参与的情况下在那里写入,并且(尽可能地)知道其他用户或机器不会干扰那里的内容。
在该目录中,您为您的程序创建一个目录,并在其中放置您想要的任何内容,只要您选择了一个唯一的名称(例如,My Unique App Name
或My Company Name\My App Name
或 UUID),您就不会与其他程序发生意外冲突。(以前在 MSDN 中对此有具体的指导,但我再也找不到了。)
那么,如何进入该目录?
最简单的方法是只使用 env 变量%LOCALAPPDATA%
。如果您需要处理较旧的 Windows,您可以使用%USERPROFILE%
并\Local Settings\Application Data
粘贴到最后,这可以保证是相同的,或者通过连接在同一个地方结束。
您还可以使用pywin32
或ctypes
访问本机 Windows API(因为至少有 3 种不同的 API 和至少两种访问这些 API 的方法,我不想给出所有可能的方法来编写这个……但是快速谷歌或搜索“pywin32 SHGetFolderPath”或“ctypes SHGetKnownFolderPath”或任何应该给你你需要的东西)。
或者,有多个第三方模块来处理这个问题。Google 和 PyPI 出现的第一个是winshell
.
不保证 PYC 文件与不同的 python 版本兼容。如果您不知道所有客户都运行相同的 python 版本,那么您真的不想直接分发 pyc。因此,您必须在分发 PYC 和支持多个 python 版本之间做出选择。
您可以创建构建过程,使用py_compile编译所有文件并将它们压缩到特定于版本的包中。您可以使用setuptools 执行此操作。; 但是这样做会很尴尬,因为您必须在需要支持的每个版本中运行 py_compile。
如果您基本上是在分发一个封闭的应用程序并且不希望人们对您的源代码进行微不足道的访问,那么py2exe可能是一个更简单的选择。如果您的 python 应该集成到用户的 python 安装中,那么只需创建一个 .py 文件的 zip 并添加一个使用zipfile导入压缩包的单行 .py 存根可能会更简单
如果它让你感觉更好,PYC 不会提供太多额外的安全性,也不会真正提高性能:)