繁体   English   中英

如何正确初始化 win32com.client.constants?

[英]How to properly initialize win32com.client.constants?

我正在编写一个简单的 email 过滤器来处理 Windows 10 上的 Outlook 传入消息,并试图使用 Anaconda 下的win32com库在 Python 中对其进行编码。我还试图避免在“收件箱”中使用幻数在其他示例中,宁愿使用win32com.client.constants下定义的常量。 但是我遇到了令人惊讶的简单错误:

因此,我大致基于https://stackoverflow.com/a/65800130/257924编写了以下简单代码:

import sys
import win32com.client

try:
    outlookApp = win32com.client.Dispatch("Outlook.Application")
except:
    print("ERROR: Unable to load Outlook")
    sys.exit(1)

outlook = outlookApp.GetNamespace("MAPI")
ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
print("ofContacts", type(ofContacts))
sys.exit(0) 

在基于 Anaconda 的安装程序(Anaconda3 2022.10(Python 3.9.13 64 位))下运行 Windows 出现 10 个错误:

(base) c:\Temp>python testing.py
Traceback (most recent call last):
  File "c:\Temp\testing.py", line 11, in <module>
    ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
  File "C:\Users\brentg\Anaconda3\lib\site-packages\win32com\client\__init__.py", line 231, in __getattr__
    raise AttributeError(a)
AttributeError: olFolderContacts

进一步调试发现,上述错误信息中的__init__.py引用了__dicts__属性。 请参阅下面的 class 的摘录。 出于某种原因, __dicts__是一个空列表:

class Constants:
    """A container for generated COM constants."""

    def __init__(self):
        self.__dicts__ = []  # A list of dictionaries

    def __getattr__(self, a):
        for d in self.__dicts__:
            if a in d:
                return d[a]
        raise AttributeError(a)


# And create an instance.
constants = Constants()

win32com正确初始化constants object 需要什么?

如果相关, init .py 文件上的时间戳显示 10/10/2021。

简短的回答是改变:

outlookApp = win32com.client.Dispatch("Outlook.Application")

outlookApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")

更长的答案是win32com可以通过以下两种方式之一使用 COM 接口: late-绑定和early-binding

使用late-binding ,您的代码对 Dispatch 接口一无所知。 不知道哪些方法、属性或常量可用。 当您调用 Dispatch 接口上的方法时, win32com不知道该方法是否存在或任何参数:它只是发送给定的内容并希望最好!

使用early-binding ,您的代码依赖于先前捕获的有关 Dispatch 接口的信息,这些信息取自其类型库。 此信息用于为知道所有方法及其参数的接口创建本地 Python 包装器。 同时,它使用类型库中包含的任何常量/枚举填充常量字典。

win32com有一个包罗万象的win32com.client.Dispatch() function 如果存在本地包装文件,它将尝试使用早期绑定,否则将退回到使用后期绑定。 我对 package 的问题是呼叫者并不总是知道他们得到了什么,就像 OP 的情况一样。

替代方案win32com.client.gencache.EnsureDispatch() function 强制执行早期绑定并确保任何常量可用 如果本地包装文件不可用,将创建它们(您可能会在 %LOCALAPPDATA%\Temp\gen_py\xx\CLSID 下找到它们,其中 xx 是 Python 版本号,CLSID 是类型库的 GUID)。 一旦创建了这些包装器,通用win32com.client.Dispatch()将使用这些文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM