1

Introduction

I have a script which uses SSL and is build with py2exe (bundle_files=1, pack everything together into the *.exe)

Now I faced this problem

Running py2exe on Win7 creates an *.exe which will run in Win7 and Win10
Running py2exe on Win10 creates an *.exe which will run in Win10 but produces this error in Win7:

ImportError: MemoryLoadLibrary failed loading _ssl.pyd

Workaround

Setting bundle_files to 3 (don't pack) will result in an *.exe which is working fine in Win7 even when it is built on Win10.

I tried out some py2exe options and suddenly it worked, when changing bundle_files. But I don't understand why.

My setup

  • python 32bit 2.7.11
  • ssl.OPENSSL_VERSION => 'OpenSSL 1.0.2d 9 Jul 2015'
  • py2exe 0.6.9

Same on both machines (win7 and win10).

This is a minimal demo to reproduce it:

demo.py

import ssl
print "import done"

It can be built using this
exebuilder.py

from distutils.core import setup
import py2exe
import sys

sys.argv.append("py2exe") # run py2exe (instead of supplying the command line argument)

# exclude some DLLs
dll_excludes = [
    # win9x leftovers
    "w9xpopen.exe",
    # don't import these - otherwise win7 created *.exe won't work in winXP
    # http://stackoverflow.com/questions/1979486/py2exe-win32api-pyc-importerror-dll-load-failed
    "mswsock.dll",
    "powrprof.dll"
]
sys.argv.append("--dll-excludes=%s" % ",".join(dll_excludes))

app_name = "win10ssl"
params = {
    'zipfile': None, # pack everything into the *.exe
    'options': {
        "py2exe": {
            "compressed": 1,
            "optimize": 2,
            # bundle_files
            # 1 = EVERYTHING packed into the *.exe
            # 2 = everything except for the pythonXX.dll
            # 3 = don't pack
            "bundle_files": 3
        }
    },
    'version': "0.0.1.0",
    'description': "demo to show MemoryLoadLibrary error",
    'name': app_name,
    'console': [{
            "script": "demo.py",
            "dest_base": app_name
        }
    ]
}

setup(**params)
snodo
  • 168
  • 1
  • 9

1 Answers1

4

Add "crypt32.dll" and "mpr.dll" to your dll_excludes. These are loaded by _ssl.pyd in newer versions of Python such as 2.7.11. But these libraries are Windows system libraries and OS version dependent, so they should not be packaged and distributed with your project. The Win7 "crypt32.dll" probably works on Win10, but the Win10 "crypt32.dll" most likely won't work on Win7.

  • Excluding crypt32.dll did the trick! I still don't really understand why: When bundle_files was set to 3 there was a crypt32.dll in the "dist" directory. Why does Win7 not use this one (win10 version) but when it's bundled into the *.exe it IS used? I would have expected when running the *.exe it will try to use the *.dll-files in its one directory with highest priority. – snodo Jun 30 '16 at 08:01