python-win32 com excel com模型开始生成错误

tzxcd3kk  于 2022-11-26  发布在  Python
关注(0)|答案(6)|浏览(265)

在过去的几天里,我一直在为许多报表自动生成一些数据透视表。
最低限度来说,以下代码可以正常工作:

import win32com.client    
objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
objExcelApp.Visible = 1

这将弹出一个excel的示例,我可以继续用Python工作。但是突然,今天我的脚本失败了,出现了以下错误:

>>>import win32com.client
>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
    mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 391, in EnsureModule
    module = GetModuleForTypelib(typelibCLSID, lcid, major, minor)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 266, in GetModuleForTypelib
    AddModuleToCache(typelibCLSID, lcid, major, minor)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 552, in AddModuleToCache
    dict = mod.CLSIDToClassMap
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'CLSIDToClassMap'

代码从昨天到今天都没有改变。我不知道发生了什么!!!。
另一个有趣的问题是,如果我在同一会话中再次执行相同的代码,我会得到一个不同的错误:

>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
    mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 447, in EnsureModule
    if module.MinorVersion != tlbAttributes[4] or genpy.makepy_version != module.makepy_version:
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'MinorVersion'
>>>

因此,我跳到一个windows机器与一个新的windows安装,安装python37和pip安装pypiwin 32。运行非常相同的行和excel打开就像它昨天在我原来的机器上。
我试着卸载和重新安装没有运气。你知道这是怎么回事吗?
注:动态调度仍然有效:

import win32com.client
objExcelApp = win32com.client.Dispatch("Excel.Application")
objExcelApp.Visible = 1

但是我特别需要静态调度,因为Pivot Tables不能使用动态调度的对象(在我的代码后面很久才能看到):

objExcelPivotCache = objExcelWorkbook.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=objExcelPivotSourceRange)
d7v8vwbk

d7v8vwbk1#

我遇到了同样的问题,我按照这里的说明解决了它:https://mail.python.org/pipermail/python-win32/2007-August/006147.html
删除gen_py输出目录并重新运行makepy SUCCEEDS,随后测试应用程序再次正常运行。
所以症状已经解决了,但是任何线索都不能说明这是如何发生的。这是一个运行时间很长的应用程序(想想24 x7几年),我担心无论是什么原因导致的这种情况可能会再次发生。
要查找输出目录,请在python控制台/ python会话中运行以下命令:

import win32com
print(win32com.__gen_path__)

根据您帖子中的异常消息,您需要删除的目录将命名为“00020813-0000- 0000-C 000 - 000000000046 x 0x 1x 9”。因此,删除此目录并重新运行代码。如果您对删除它感到紧张(像我一样),只需剪切此目录并将其粘贴到其他位置。
💡请注意,此目录通常位于“TEMP”目录中(在Windows文件资源管理器中复制并粘贴%TEMP%/gen_py,您将直接到达该目录)。
我不知道为什么会发生这种情况,也不知道如何防止它再次发生,但我提供的链接中的指示似乎对我有用。

9jyewag0

9jyewag02#

一个更直接的解决方案被张贴在一个相关的问题Issue in using win32com to access Excel file
基本上,您只需要删除文件夹C:\Users\<your username>\AppData\Local\Temp\gen_py并重新运行代码。
💡提示:你也可以把你的Windows文件资源管理器%TEMP%\gen_py直接访问它,然后删除它的内容。

ca1c2owp

ca1c2owp3#

在powershell或cmd中执行此命令行(不在管理员模式下=〉对我不起作用)

python -m win32com.client.makepy "Excel.Application"

它修复了所有的错误,你不必修改你的python代码。

win32com.client.gencache.EnsureDispatch("Excel.Application")

通过gencache.EnsureDispatch,您可以访问makepy动态加载的应用程序的常量,该应用程序必须具有注册的应用程序(在我们的示例中为Excel.Application)。如果您在Outlook中遇到同样的问题,请使用上面的“Outlook.Application”。
如果仍然不工作,请重新安装python发行版的pywin32

<path to python root or venv>\pip.exe uninstall pywin32
<path to python root or venv>\pip.exe install pywin32
v64noz0r

v64noz0r4#

对我有效的方法是:

excel = win32.gencache.EnsureDispatch('Excel.Application')
#change to =>
excel = win32.Dispatch('Excel.Application')
jaxagkaj

jaxagkaj5#

对我来说,问题似乎是我有多个进程通过win32com与Windows应用程序交互。
由于win32comwin32api.GetTempPath()中创建了“gen_py”目录,这可能会导致冲突和该高速缓存损坏。
我的解决方案是为每个进程设置一个“gen_py”的自定义位置。

from pathlib import Path
import win32com

gen_py_path = '/some/custom/location/gen_py'

Path(gen_py_path).mkdir(parents=True, exist_ok=True)
win32com.__gen_path__ = gen_py_path

# Any other imports/code that uses win32com

这样你就不必删除默认的“gen_py”文件夹,也不必担心会出现什么问题。但是如果你仍然发现需要删除,你可以只删除自定义文件夹,并知道你只是为了这个过程而删除该高速缓存。

xtfmy6hx

xtfmy6hx6#

为了补充此讨论,对于那些在无人监督的自动化过程中收到此错误的人,您可以完全自动化恢复过程,并允许任何过程在无人监督的情况下继续进行。
正如Ian和Qin提到的,我们需要删除gen_py输出目录并重新启动该过程。gen_py输出目录是一个可以更改的临时目录,并且当前运行的依赖于gen_py的进程即使在重新生成该目录之后也会继续失败。
为了解决这些问题,我们可以动态查找位置,然后我们可以完全摧毁整个进程并重新启动它。我已经尝试删除并重新导入win32com,但似乎仍然保留了对损坏的缓存的引用,因此整个进程需要重新启动。

temp_data_dir = os.environ.get('LOCALAPPDATA'))
gen_py_dir = ''
for curr_path, dirs, files, in walk(temp_data_dir)
    if 'gen_py' in dirs:
        gen_py_dir = Path(curr_path).joinpath('gen_py')

shutil.rmtree(gen_py_dir)
execv(restart_args)

重新启动的进程应再次调用win32com.client.gencache.EnsureDispatch('Excel.Application'),现在将使用gen_py的新副本,然后我们可以重试失败的Excel自动化代码。
这个问题以一种完全不可靠的方式偶尔发生,我无法复制。我最好的猜测是gen_py缓存有时会以某种方式损坏,需要刷新。

相关问题