我有一个导入win32clipboard
的Python 2.7程序。我尝试在Windows XP SP3 32位上使用cx_Freeze 4.2.3冻结它,以创建安装MSI。我根据cx_Freeze文档制作了setup.py
,并使用了以下命令:
c:\python27\python.exe setup.py bdist_msi
当我在没有安装Python 2.7的另一台PC上运行时,我在导入win32clipboard
的行上遇到异常:
ImportError: DLL load failed: The specified module could not be found.
我可以看到win32clipboard.pyd
包含在构建中。
缺少什么依赖关系,如何确保包含它?
答案 0 :(得分:4)
我最终认为win32clipboard.pyd
是,但是,win32clipboard.pyd
取决于pywintypes27.dll
,其中cx_Freeze 不复制来自c:\windows\system32
。
短期黑客攻击是将c:\windows\system32\pywintypes27.dll
手动复制到build\exe.win32-2.7
,然后再次运行setup.py bdist_msi
。
改进的hack是在setup.py中使用以下内容:
import os
import sys
import win32api
...
pywintypes_dll = 'pywintypes{0}{1}.dll'.format(*sys.version_info[0:2]) # e.g. pywintypes27.dll
build_exe_options = {..., "include_files": [ (os.path.join(win32api.GetSystemDirectory(), pywintypes_dll), pywintypes_dll)]}
...
setup( ...,
options = { 'build_exe': build_exe_options,
...,
},
...)
(最好改进cx_Freeze以自动检测pywintype27.dll
依赖关系,但我想这总是在进行中。)
答案 1 :(得分:2)
cx_Freeze使用挂钩机制来处理这种情况。钩子存储在模块cx_Freeze.hooks
中。每个钩子都以被调查的动作,加载或缺失以及模块名称命名。该模块本身提供了大量示例。
以下是处理win32clipboard模块的方法:
from cx_Freeze import hooks
def load_win32clipboard(finder, module):
finder.IncludeModule("pywintypes")
hooks.load_win32clipboard = load_win32clipboard
...
现在当cx_Freeze遇到win32clipboard时,它还会包含pywintypes。 cx_Freeze已经有一个pywintypes钩子,它将复制相应的文件。