gpt4 book ai didi

来自不同线程的 Pythoncom PumpMessages

转载 作者:行者123 更新时间:2023-11-28 17:00:38 60 4
gpt4 key购买 nike

我想做类似于要求的事情 here , 但使用 threadinghere .也使用来自 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 但没有单独的线程)时,它可以工作并且电子邮件在到达时被识别,但显然线程被阻塞,甚至 KeyboardInterrupt 异常都不能捕获了。

那么,如何让 outlook watcher 在单独的线程中运行,将消息发送到主线程输出呢?

最佳答案

格式正确的问题,附有引用资料。谢谢。

到答案。在这种情况下,我使用 ``threading.Thread(target= ....`。但是您也可以使用继承:

import logging
import threading
import time


def task(name):
log = logging.getLogger('task-' + name)
log.info("Starting up Outlook watcher\n"
"To terminate the program, press 'Ctrl + C'")
while True:
log.info("Doing work that takes time")
time.sleep(1)


class OtlkThread(threading.Thread):

def __init__(self, *args, **kwargs):
self.log = logging.getLogger('task-class')
super().__init__(*args, **kwargs)

def run(self):
self.log.info("Starting up Outlook watcher\n"
"To terminate the program, press 'Ctrl + C'")
while True:
self.log.info("Doing work that takes time")
time.sleep(1)

def main():
t1 = threading.Thread(target=task, args=('daemon',), daemon=True)
t1.start()
t2 = OtlkThread()
t2.start()


if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG,)

main()
while True:
time.sleep(1)

关于来自不同线程的 Pythoncom PumpMessages,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54787608/

60 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com