我想做一些类似于here的操作,但是使用threading
就像here。同时使用来自here的答案,我让我的代码正常工作,只是一个ItemAdd事件没有被识别(实际上,我认为是,但在另一个线程中,这就是为什么没有输出)。在
"""Handler class that watches for incoming mails"""
import ctypes # for the WM_QUIT to stop PumpMessage()
import logging
import win32com.client
import sys
import threading
import time
import pythoncom
# outlook config
CENTRAL_MAILBOX = "My Mailbox"
# get the outlook instance and inbox folders
outlook = win32com.client.Dispatch("Outlook.Application")
marshalled_otlk = pythoncom.CoMarshalInterThreadInterfaceInStream(
pythoncom.IID_IDispatch, outlook)
class HandlerClass(object):
def OnItemAdd(self, item):
logger.info("New item added in central mailbox")
if item.Class == 43:
logger.info("The item is an email!")
class OtlkThread(threading.Thread):
def __init__(self, marshalled_otlk, *args, **kwargs):
super().__init__(*args, **kwargs)
self.marshalled_otlk = marshalled_otlk
self.logger = logging.getLogger("OLThread")
def run(self):
self.logger.info("Starting up Outlook watcher\n"
"To terminate the program, press 'Ctrl + C'")
pythoncom.CoInitialize()
outlook = win32com.client.Dispatch(
pythoncom.CoGetInterfaceAndReleaseStream(
self.marshalled_otlk,
pythoncom.IID_IDispatch
)
)
user = outlook.Session.CreateRecipient(CENTRAL_MAILBOX)
central_inbox = outlook.Session.GetSharedDefaultFolder(user, 6).Items
self.logger.info(f"{central_inbox.Count} messages in central inbox")
win32com.client.DispatchWithEvents(central_inbox, HandlerClass)
pythoncom.PumpMessages()
pythoncom.CoUninitialize() # this is prbly unnecessary as it will never be reached
def main():
# pythoncom.CoInitialize()
OtlkThread(marshalled_otlk, daemon=True).start()
if __name__ == "__main__":
status = main()
while True:
try:
# pythoncom.PumpWaitingMessages()
time.sleep(1)
except KeyboardInterrupt:
logger.info("Terminating program..")
ctypes.windll.user32.PostQuitMessage(0)
sys.exit(status)
我尝试过各种方法,比如将sys.coinit_flags=0
放在顶部,如建议的here)、在主线程中调用PumpWaitingMessages()
,并将Outlook应用程序放在副线程中,而不是传递封送的对象。这些都没有奏效。在
当我把PumpMessages放入主线程(相同的HandlerClass
但没有单独的线程)时,它可以工作,电子邮件在到达时被识别,但是很明显线程被阻塞了,甚至连键盘中断异常都无法捕捉到。在
那么,如何让outlookwatcher在单独的线程中运行,将消息发送到主线程以在那里输出呢?在
再次感谢您的回答,Michael,它让我找到了this答案,其中还包含一个excellent example的链接。这个答案和示例的主要收获是,不要将Outlook作为封送处理程序传递,而是将其作为客户端传递给处理程序。另外,使用}。在
WithEvents
代替DispatchWithEvents
,并在导入pythoncom
之前设置{最终结果如下:
格式很好的问题,有参考资料。谢谢。在
答案。我使用``线程。线程(在这种情况下,目标=…`。但是,您也可以使用继承:
相关问题 更多 >
编程相关推荐