ImportError with cx_freeze and pywin32: Module 'pythoncom' isn't in frozen sys.path
Asked Answered
C

6

2

I am attempting to create a .exe on Windows 7 from a python3 script using cx_freeze. the Script involves using pywin32 to manipulate Excel files. I can build the .exe successfully from my setup.py file; however, when I run the .exe, the following error is thrown:

Traceback (most recent call last):

File "C:\Python33\lib\site-packages\cx_Freeze\initscripts\Console3.py", line 27, in exec(code,m_dict_)

File "MyScript.py", line 12, in < module >

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1558, in _find_and_load

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1505, in _find_and_load_unlocked

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 313, in _call_with_frames_removed

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1558, in _find_and_load

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1525, in _find_and_load_unlocked

File "C:\Python33\lib\site-packages\win32com__init__.py", line 6, in < module>

import pythoncom

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1558, in _find_and_load

File "C:\Python\64-bit\3.3\lib\importlib_bootstrap.py", line 1525, in _find_and_load_unlocked

File "C:\Python33\lib\site-packages\pythoncom.py", line 3, in
pywintypes._import_pywin32_system_module_("pythoncom", globals())

File "C:\Python33\lib\site-packages\win32\lib\pywintypes.py", line 61, in _import_pywin32_system_module_

raise ImportError("Module '%s' isn't in frozen sys.path %s" % (modname, sys.path))

ImportError: Module 'pythoncom' isn't in frozen sys.path

['C:\Python33\build\exe.win-amd64\3.3\MyScript.exe',

'C:\Python33\build\exe.win-amd64\3.3',

'C:\Python33\build\exe.win-amd64\3.3\MyScript.zip',

'C:\Python33\build\exe.win-amd64\3.3\library.zip']

Here is what my setup.py file currently looks like:

import sys
from cx_Freeze import setup, Executable

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

includes = []
packages = []
executables = [Executable('MyScript.py', base=base)]
include_files = ['MyFolder1/','MyFolder2/Spreadsheet.xls']

setup(name='My Script',
      version='0.1',
      description='My Script',
      executables=executables,
      options = {'build_exe': {'includes':includes,
                               'packages':packages,
                               'include_msvcr':True,
                               'include_files':include_files}})

So far, I have tried listing both 'pythoncom' and 'win32com' in both the includes and the packages lists. Any help is greatly appreciated!

Chancroid answered 26/7, 2013 at 21:9 Comment(0)
S
4

I had exactly the same issue when using pyinstaller to pack py into executable. Tried everything, but find out the issue is hidden in pyinstaller version. I was using pyinstaller 4.7 but when downgrade into 3.6, the exe works flawlessly.

Subroutine answered 10/12, 2021 at 22:6 Comment(2)
downgrading from pyinstaller 4.7 to 4.4 seems to be working okThreadfin
@Louis-PhilippeDescamps ahh. True. Not sure what is going on with 4.7Subroutine
R
2

Looking at the code, it looks like you need to ensure that a file called something like pythoncom33.dll is copied into the build directory.

Rother answered 29/7, 2013 at 13:59 Comment(1)
This is the real solution to any 'module not found' issues when 'freezing' python apps.Clinical
C
2

So the whole problem actually stemmed from having the 32-bit version of pywin32 installed while running 64-bit versions of Python-3.3.2 and Windows 7. After adding pythoncom33.dll to the include_files of my setup.py as Thomas K had suggested, I got another error:

ImportError: DLL load failed: %1 is not a valid Win32 application

After some research, I found that this error is typical when mixing 32-bit and 64-bit. So I uninstalled pywin32 32-bit and installed pywin32 64-bit but my script threw yet another error:

import win32api, sys, os

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

As suggested in this post, I copied the 28 win32*.pyd files from the Lib/site-packages/win32 folder to the Python33 folder right next to python.exe , and everything worked.

Chancroid answered 30/7, 2013 at 14:42 Comment(1)
Thomas's answer seems the correct one (I got the same error as the OP and his answer solved it), while this answer only fix a possible secondary problem. IMO this answer should be merged to Thomas's answer.Allemande
G
1

Add this to the top of your main.py:

import pywintypes

import win32api

see: PyWin32 and Python 3.8.0

Gourmet answered 2/4, 2022 at 9:33 Comment(1)
This worked for me well on 3.10 ;)Veterinarian
U
0

So I ran into a similar problem where cx_Freeze was failing to pull in the pywintypes DLL, but frustratingly enough it was only on some machines which compelled me to explore the issue a bit further (I have a bad habit of chasing rabbits down holes). It seems that pywin32 tries to install its DLLs into a Windows system directory, but if that fails due to a lack of privileges it will fallback to placing them in your Python directory instead. The behavior I was seeing was a result of the fact that cx_Freeze applies a blacklist of well-known system folder paths against the collection of dependencies it has discovered in order to avoid pulling in operating system DLLs.

Copying these DLLs as needed by adding a path to them to the "include_files" parameter will indeed address the issue (just remember that you can't guarantee that they will be placed in the system folder). An alternative solution is to override the blacklist with a whitelist which you can configure using the "bin_includes" / "bin_path_includes" parameters. Here is a quick example that shows how to configure this parameter using a setup.py file (for Python 2.7, but the only difference should be the pywintypes DLL filename):

from cx_Freeze import setup, Executable

# This can also be an absolute path to the file if you wish to be very specific
bin_includes = ["pywintypes27.dll"]

options = {
    "build_exe": {
        "bin_includes": bin_includes
    }
}

executable = Executable(script='main.py')

setup(version='x.x.x',
      options=options,
      executables=[executable])
Unconformable answered 1/4, 2015 at 23:22 Comment(0)
P
0

Update pyinstaller related vision.

python -m pip install pyinstaller==3.6
Parlay answered 10/1, 2022 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.