PyWin32 和 Python 3.8.0

PyWin32 and Python 3.8.0

Python 3.8.0 最近发布了(在 20191014,可以从 [=14= 下载](于20190915发布)。不幸的是,在pip installing之后,它不起作用。

样本:

[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\q058631512]> sopr.bat
*** Set shorter prompt to better fit when pasted in Whosebug (or other) pages ***

[prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe"
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api
>>> ^Z


[prompt]> "e:\Work\Dev\VEnvs\py_064_03.08.00_test0\Scripts\python.exe"
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: DLL load failed while importing win32api: The specified module could not be found.
>>> ^Z

备注:

剧透警告!!!

#2.2.(从下)应用到原来的.whls,并在 [GitHub]: CristiFati/Prebuilt-Binaries - (master) Prebuilt-Binaries/PyWin32/v225 上发布(win_amd64win32 for Python3.8).

安装(其中一个)后,现有代码应该可以工作 OOTB(关于这个问题)。

安装步骤:

  1. 下载符合您的Python架构的.whl64位32 位 - 有关获取 Python 架构的更多详细信息,请查看 [SO]: How do I determine if my python shell is executing in 32bit or 64bit mode on OS X? (@CristiFati's answer)(问题是关于 OSX,但也包括其他平台)),它很可能是 64bitwin_amd64),从上面的URL
    比如我下载在L:\Downloads

  2. 在其上调用 PIP 安装程序 ()。类似于:

    (${path_to_your})python.exe -m pip ${path_to_the_downloaded_pywin32_whl}
    

    示例:

    "e:\Work\Dev\VEnvs\py_pc064_03.08.00_test0\Scripts\python.exe" -m pip "L:\Downloads\pywin32-225-cp38-cp38-win_amd64.whl"
    


问题已在 [GitHub]: mhammond/pywin32 - python 3.8 上报告。

以上URL再引用2个:

  • [Python 3.8.Docs]: What’s New In Python 3.8 - Changes in the Python API 其中指出(重点 是我的):
    • DLL dependencies for extension modules and DLLs loaded with ctypes on Windows are now resolved more securely. Only the system paths, the directory containing the DLL or PYD file, and directories added with add_dll_directory() are searched for load-time dependencies. Specifically, PATH and the current working directory are no longer used, and modifications to these will no longer have any effect on normal DLL resolution.
  • [Python 3.Docs]: os.add_dll_directory(path) 其中指出(强调 仍然是我的):

    This search path is used when resolving dependencies for imported extension modules (the module itself is resolved through sys.path), and also by ctypes.

与此同时,我自己进行了一些挖掘,发现(对于 win32api.pyd)它是 pywintypes38.dll(这是 .pyds 的依赖项)未找到(我还在对该问题的评论中指定了这一点)。

解决方案(实际上是解决方法(或多或少),直到发布官方和向后兼容的修复程序):

  1. 通过导入强制pywintypes38.dll加载(因为它也是一个Python模块,在这种情况下它不属于上述规则) before any PyWin32 module:

     import pywintypes
     import win32api
    

    如果使用 COM,您需要 import pythoncom

  2. pywin32_system32添加到.dll搜索路径(遵循上面的新模型) .有多种方式:

    1. v-python 对问题 URL 的评论提供一小段(我没有测试)

    2. 我也提交了[GitHub]: mhammond/pywin32 - Support for Python 3.8, where I do everything in the pywin32.pth file ("executed" when the interpreter starts, so no changes needed for existing code). Unfortunately, there is a problem with the AppVeyor automated tests which fail (but for some other reasons), so it has been stuck there for a while. Note that in the meantime, the PR was closed and another (similar) approach was pushed. Note that v226 (released on 20191110) which contains the fix, does not work on VirtualEnv ()。
      无论如何,在本地应用更改 (1)(在我的两个 Python VirtualEnvs), 解决了问题(在一个上,并没有破坏另一个):

      [cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\q058631512]> sopr.bat
      *** Set shorter prompt to better fit when pasted in Whosebug (or other) pages ***
      
      [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" -c "import win32api"
      
      [prompt]> "e:\Work\Dev\VEnvs\py_064_03.08.00_test0\Scripts\python.exe" -c "import win32api"
      
      [prompt]>
      
    3. 其他方式,例如复制 .dlls(例如 %SystemRoot%\System32),或 symlinking 他们,但(个人)我不推荐那些



更新#0

[PyPI]: pywin32 227(解决了这个问题),发表于 20191114!



脚注

  • #1:检查修补utrunner 部分)了解如何应用补丁(在 Win 上)。

设法在 python 3.8 上使用 pycharm 安装 pywin32 v225。

win32api

之前导入 pywintypes
import pywintypes
import win32api