ImportError:导入使用cx_Freeze冻结的应用程序中的win32clipboard时DLL加载失败

我有一个导入win32clipboard的Python 2.7程序。 我尝试在Windows XP SP3 32位上使用cx_Freeze 4.2.3来冻结它,以创build一个安装MSI。 我根据cx_Freeze文档创build了一个setup.py ,并使用了以下命令:

 c:\python27\python.exe setup.py bdist_msi 

当我在没有安装Python 2.7的另一台PC上运行它时,在importwin32clipboard的行上出现exception:

 ImportError: DLL load failed: The specified module could not be found. 

我可以看到win32clipboard.pyd 正在被包含在构build中。

缺less什么依赖关系,如何确保它包含在内?

我最终认为, win32clipboard.pyd 正在被包括,但是, win32clipboard.pyd依赖于pywintypes27.dll ,其中cx_Freeze 不是c:\windows\system32复制。

短期攻击是手动将c:\windows\system32\pywintypes27.dllbuild\exe.win32-2.7 ,然后再次运行setup.py bdist_msi

改进的黑客是在setup.py中使用以下内容:

 import os import sys import win32api ... pywintypes_dll = 'pywintypes{0}{1}.dll'.format(*sys.version_info[0:2]) # eg 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依赖项,但我想这总是一个进行中的工作。)

cx_Freeze使用钩子机制来处理这种情况。 挂钩存储在模块cx_Freeze.hooks 。 每个钩子都是在调查,加载或丢失的操作以及模块名称后命名的。 模块本身提供了很多例子。

以下是你如何处理win32clipboard模块:

 from cx_Freeze import hooks def load_win32clipboard(finder, module): finder.Includemodulee("pywintypes") hooks.load_win32clipboard = load_win32clipboard ... 

现在当cx_Freeze遇到win32clipboard时,它也会包含pywintypes。 cx_Freeze已经有了一个pywintypes钩子来复制相应的文件。