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

时间:2012-06-21 02:01:15

标签: python windows pywin32 cx-freeze

我有一个导入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 包含在构建中。

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

2 个答案:

答案 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钩子,它将复制相应的文件。