pyimod04_pywin32.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #-----------------------------------------------------------------------------
  2. # Copyright (c) 2005-2023, PyInstaller Development Team.
  3. #
  4. # Distributed under the terms of the GNU General Public License with exception
  5. # for distributing bootloader.
  6. #
  7. # The full license is in the file COPYING.txt, distributed with this software.
  8. #-----------------------------------------------------------------------------
  9. """
  10. Set search path for pywin32 DLLs. Due to the large number of pywin32 modules, we use a single loader-level script
  11. instead of per-module runtime hook scripts.
  12. """
  13. import os
  14. import sys
  15. def install():
  16. # Sub-directories containing extensions. In original python environment, these are added to `sys.path` by the
  17. # `pywin32.pth` so the extensions end up treated as top-level modules. We attempt to preserve the directory
  18. # layout, so we need to add these directories to `sys.path` ourselves.
  19. pywin32_ext_paths = ('win32', 'pythonwin')
  20. pywin32_ext_paths = [os.path.join(sys._MEIPASS, pywin32_ext_path) for pywin32_ext_path in pywin32_ext_paths]
  21. pywin32_ext_paths = [path for path in pywin32_ext_paths if os.path.isdir(path)]
  22. sys.path.extend(pywin32_ext_paths)
  23. # Additional handling of `pywin32_system32` DLL directory
  24. pywin32_system32_path = os.path.join(sys._MEIPASS, 'pywin32_system32')
  25. if not os.path.isdir(pywin32_system32_path):
  26. # Either pywin32 is not collected, or we are dealing with version that does not use the pywin32_system32
  27. # sub-directory. In the latter case, the pywin32 DLLs should be in `sys._MEIPASS`, and nothing
  28. # else needs to be done here.
  29. return
  30. # Add the DLL directory to `sys.path`.
  31. # This is necessary because `__import_pywin32_system_module__` from `pywintypes` module assumes that in a frozen
  32. # application, the pywin32 DLLs (`pythoncom3X.dll` and `pywintypes3X.dll`) that are normally found in
  33. # `pywin32_system32` sub-directory in `sys.path` (site-packages, really) are located directly in `sys.path`.
  34. # This obviously runs afoul of our attempts at preserving the directory layout and placing them in the
  35. # `pywin32_system32` sub-directory instead of the top-level application directory.
  36. sys.path.append(pywin32_system32_path)
  37. # Add the DLL directory to DLL search path using os.add_dll_directory().
  38. # This allows extensions from win32 directory (e.g., win32api, win32crypt) to be loaded on their own without
  39. # importing pywintypes first. The extensions are linked against pywintypes3X.dll.
  40. os.add_dll_directory(pywin32_system32_path)
  41. # Add the DLL directory to PATH. This is necessary under certain versions of
  42. # Anaconda python, where `os.add_dll_directory` does not work.
  43. path = os.environ.get('PATH', None)
  44. if not path:
  45. path = pywin32_system32_path
  46. else:
  47. path = pywin32_system32_path + os.pathsep + path
  48. os.environ['PATH'] = path