自动化办公|Python 使用 win32com 模块报错踩坑分享

前言

文章首发于个人公号:可乐python说

最近,需要使用 Python 实现一些自动化办公的业务,之前使用过其他的包,但存在一些局限性,于是本次选择 win32com 来实现,环境是 win10,首先我们安装 pywin32

pip install pywin32

安装过程很顺利,并无异常出现,于是开心的码上 demo ,运行时居然报错了,一顿折腾后,于是就有了这篇文章。

Demo 示例代码

import win32com

app = win32com.client.Dispatch('Word.Application')
# 打开文件并展示
app.Visible = True
app.Documents.Open("F:\\learning\\wincom32_demo\\demo.doc")

运行报错

运行时报如下错误:

  File "F:/learning/wincom32_demo/win32com_demo.py", line 5, in <module>
    app = win32com.client.Dispatch('Word.Application')
AttributeError: module 'win32com' has no attribute 'client'

Process finished with exit code 1

报错信息提示 win32com 模块没有 client 属性,于是我做了如下尝试,因为之前遇到过类似的情况,我首先考虑的是版本问题,卸载、重装,反反复复。

降低版本尝试

pip install pywin32==227
pip install pywin32==226
pip install pywin32==225
pip install pywin32==224
pip install pywin32==223
pip install pywin32==222
...

逐个降版本,依然不可行。

版本降到 222 时,提示缺少 Dll 文件,那是不是相关 C++ 的依赖需要更新完善呢,我检查电脑上的 Microsoft Visual C++ 相关依赖,貌似是不够全,于是我安装了相关的依赖。

完善 C++ 相关依赖

完善前我的电脑只要 2015 版本的依赖,如下图:
[图片上传失败...(image-c87c14-1597809584716)]
借用完善工具 MSVBCRT_AIO_2018.05.13_X86 X64.exe,一次性完善相关依赖,傻瓜式操作,直接下一步即可,完善后结果如下:

image

这下全拉,再次运行,果然不出所料,仍然报同样的错误,下面先试试离线包方式安装。

离线包方式安装

前面尝试在命令行中安装的方式,并没有解决报错问题,现在试试离线包的方式:

1、先从 pypi 下载离线包 pywin32 228 版本,下载的文件名为 pywin32-228-cp36-cp36m-win32.whl

image

2、进入下载目录,打开命令行工具执行以下命令

pip install pywin32-228-cp36-cp36m-win32.whl

3、安装成功,报错仍然存在

源码浏览

在 win32com 模块中,明明可以看到 client 模块,为啥导入使用时,就会报错呢?


进入 win32com 的初始化文件中 __init__.py 文件中看看 ,首先导入 其他几个模块 win32apipythoncom

import win32api, sys, os
import pythoncom

其他代码也并没有找到相关的有用信息

# flag if we are in a "frozen" build.
_frozen = getattr(sys, "frozen", 1==0)
# pythoncom dumbly defaults this to zero - we believe sys.frozen over it.
if _frozen and not getattr(pythoncom, "frozen", 0):
    pythoncom.frozen = sys.frozen

# Add support for an external "COM Extensions" path.
#  Concept is that you can register a seperate path to be used for
#  COM extensions, outside of the win32com directory.  These modules, however,
#  look identical to win32com built-in modules.
#  This is the technique that we use for the "standard" COM extensions.
#  eg "win32com.mapi" or "win32com.axscript" both work, even though they do not
#  live under the main win32com directory.
__gen_path__ = ''
__build_path__ = None
### TODO - Load _all_ \\Extensions subkeys - for now, we only read the default
### Modules will work if loaded into "win32comext" path.

def SetupEnvironment():
    HKEY_LOCAL_MACHINE = -2147483646 # Avoid pulling in win32con for just these...
    KEY_QUERY_VALUE = 0x1
    # Open the root key once, as this is quite slow on NT.
    try:
        keyName = "SOFTWARE\\Python\\PythonCore\\%s\\PythonPath\\win32com" % sys.winver
        key = win32api.RegOpenKey(HKEY_LOCAL_MACHINE , keyName, 0, KEY_QUERY_VALUE)
    except (win32api.error, AttributeError):
        key = None
        
    try:
        found = 0
        if key is not None:
            try:
                __path__.append( win32api.RegQueryValue(key, "Extensions" ))
                found = 1
            except win32api.error:
                # Nothing registered
                pass
        if not found:
            try:
                __path__.append( win32api.GetFullPathName( __path__[0] + "\\..\\win32comext") )
            except win32api.error:
                # Give up in disgust!
                pass
    ...

改变策略

1、改变导包方式如下:

# 直接导入 win32com 下的 client
import win32com.client

app = win32com.client.Dispatch('Word.Application')
app.Visible = True
app.Documents.Open("F:\\learning\\wincom32_demo\\demo.doc")

或者(与上面效果一样)

from win32com.client import Dispatch
app = Dispatch('Word.Application')
app.Visible = True
app.Documents.Open("F:\\learning\\wincom32_demo\\demo.doc")

2、运作成功,可正常打开准备的 Word 文件,报错消除、问题解决

结语

通过一顿折腾,总算处理了这个 bug ,bug 虐我千百遍,我待 bug 如初恋。
回过头来,会发现,其实这只是一个小问题,但排查、处理起来却需要不少时间。

在日常工作、生活中,不也是如此吗,在经历众多尝试仍不能成功时,不妨停下脚步,静一静、思考些许,换个角度看待问题,改变策略处理问题,也许问题就可被轻松解决。

希望这次分享能给遇到类似问题的朋友一些帮助,更多相关文章请前往公号:可乐python说 ,再会。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345