Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImportError: DLL load failed when importing win32clipboard in application frozen with cx_Freeze

I've got a Python 2.7 program that imports win32clipboard. I tried to freeze it with cx_Freeze 4.2.3 on Windows XP SP3 32-bit, to create an installation MSI. I made a setup.py according to the cx_Freeze documentation, and used the following command:

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

When I run it on another PC that doesn't have Python 2.7 installed, I get an exception on the line that imports win32clipboard:

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

I can see that win32clipboard.pyd is being included in the build.

What dependency is missing, and how can I ensure it is included?

like image 911
Craig McQueen Avatar asked Nov 25 '25 17:11

Craig McQueen


2 Answers

I eventually figured that win32clipboard.pyd is being included, however, win32clipboard.pyd depends on pywintypes27.dll, which cx_Freeze is not copying from c:\windows\system32.

The short-term hack is to manually copy c:\windows\system32\pywintypes27.dll into build\exe.win32-2.7, then run setup.py bdist_msi again.

An improved hack is to use the following in the 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, 
                    ...,
                  },
        ...)

(It would be preferable for cx_Freeze to be improved to automatically detect the pywintype27.dll dependency, but I guess that's always a work-in-progress.)

like image 170
Craig McQueen Avatar answered Nov 27 '25 06:11

Craig McQueen


cx_Freeze uses a hooking mechanism to handle this sort of situation. The hooks are stored in the module cx_Freeze.hooks. Each hook is named after the action being investigated, load or missing, and the module name. The module itself provides lots of examples.

Here is how you'd handle the win32clipboard module:

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

hooks.load_win32clipboard = load_win32clipboard
...

Now when cx_Freeze encounters win32clipboard, it will also include pywintypes. cx_Freeze already has a pywintypes hook that will copy the appropriate file.

like image 23
johnny Avatar answered Nov 27 '25 07:11

johnny



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!