Tags Python

I'm a happy user of py2exe for packaging Python programs into stand-alone Windows executables. The executables it creates are quite large (almost 7 MB for a program with a wxPython GUI and a few custom libraries), but they load and work very quickly and provide a very comfortable means for sending pre-packaged Python programs to people who can't or won't install Python, wxPython and a ton of other libraries just to make a program work.

Yesterday I had a first problem with py2exe packed executables. A user installed the .exe on a cleanly installed Windows PC, and got the error:

Traceback (most recent call last):
  File "perpsearch.py", line 6, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "wx\__init__.pyo", line 45, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "wx\_core.pyo", line 4, in <module>
  File "zipextimporter.pyo", line 98, in load_module
ImportError: MemoryLoadLibrary failed loading wx\_core_.pyd

After some Googling, the solution turned out to be the lack of MSVCP71.DLL on his computer. Note, this is not MSVCR71.DLL which is placed by py2exe in the dist directory, but another DLL, upon which wxPython depends. This DLL usually exists on Windows XP / Vista computers because it comes with many applications, but for fresh installs it's missing.

Thankfully, py2exe has a solution for including various DLLs inside the created .exe - described here. Basically, you have to override the function used by py2exe to decide whether to include a system DLL in the executable:

# setup.py
from distutils.core import setup
import py2exe,sys,os

origIsSystemDLL = py2exe.build_exe.isSystemDLL
def isSystemDLL(pathname):
        if os.path.basename(pathname).lower() in ("msvcp71.dll", "dwmapi.dll"):
                return 0
        return origIsSystemDLL(pathname)
py2exe.build_exe.isSystemDLL = isSystemDLL

[remainder of setup.py stuff]

This solves the problem and the executable can now run even on platforms that don't include MSVCP71.DLL.

This still leaves us with MSVCR71.DLL. This DLL is actually loaded by the executable itself, so it can't be packaged inside. If the target system is missing it, it must be packaged along-side the executable (or inside Windows' system directory by an installer). Every Windows XP SP2+ or Vista computer should have it, though, even after a fresh install.


Comments

comments powered by Disqus