Python通过win32com运行MessageQueue.Peek,如何正确设置超时时间?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python通过win32com运行MessageQueue.Peek,如何正确设置超时时间?相关的知识,希望对你有一定的参考价值。

对于初学者,我想说如果有人可以在这里提供帮助,您真是不可思议。

一般问题

我的Python程序需要与MSMQ进行交互。基本上,我想窥视一个队列,如果该队列中没有任何内容,则指定一个超时。

但是,尽管我已尽力而为,但当队列中先前没有任何值时,我无法让Peek()等待超时间隔。 您能否指出此代码中缺少的内容?


我当前的代码

现在是我的代码:

from socket import gethostname

import win32com.client
import pythoncom

import clr
clr.AddReference("System")
clr.AddReference("System.Messaging")
from System import TimeSpan
from System.Messaging import MessageQueue


# Source: [1]
# [1] https://docs.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms707027%28v%3dvs.85%29
MQ_DENY_NONE = 0x0
MQ_PEEK_ACCESS = 0x1
MQ_SEND_ACCESS = 0x2


# Set up queue
pythoncom.CoInitialize()
qinfo = win32com.client.Dispatch("MSMQ.MSMQQueueInfo")
qinfo.FormatName = f"direct=os:{gethostname()}\PRIVATE$\MyQueue"
queue = qinfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)

# Receive a value
timespan = TimeSpan.FromSeconds(timeout_sec)
label, body = "", ""
# TODO: timeout value does not appear working. It never waits when
#  there's no message
if queue.Peek(pythoncom.Empty, pythoncom.Empty, timespan):
    msg = queue.Receive() . # Blocking receive --> remove msg from the queue
    if msg is not None:
        label = msg.Label
        body = msg.Body

我运行:inspect.getfullargspec(queue.Peek)并得到:

FullArgSpec(args=['self', 'WantDestinationQueue', 'WantBody', 'ReceiveTimeout', 'WantConnectorType'], varargs=None, varkw=None, defaults=(<PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>), kwonlyargs=[], kwonlydefaults=None, annotations={})

我尝试过的事情

[This question:说ReceiveTimeout=timespan似乎无法解决我的问题。

pythoncom.Empty替换pythoncom.Missing似乎不起作用

This unanswered question似乎和我的非常相似

答案

我找到了此文章 sending-msmq-messages-python

本文向您展示了如何使用msmq发送和接收消息。我不明白为什么您不能仅使用标准的套接字连接语法来说明是否未收到数据包/连接,然后关闭连接]

import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

所以类似的事情应该不会太困难。最坏的情况是创建一个线程,该线程检查每个timeout_time变量是否为零。如果它为零,则关闭队列,如果> 0设置为零,则什么也没有收到,并等待更多消息。我还找到了一个有关异步msmq的python日志记录的GitHub。 asynchronous msmq 刚才说这是真的 dlopes7 msmq

import time
t_end = time.time() + 60 * 15
messages=0
while time.time() < t_end or messages>0:
    msg = queue.Receive()
    messages+=1
    if(time.time() > t_end and messages>0):
        messages=0
        t_end = time.time() + 60 * 15
    print(f'Got Message from {queue_name}: {msg.Label} - {msg.Body}')

不是您想要的答案,而是一个有效的答案。

以上是关于Python通过win32com运行MessageQueue.Peek,如何正确设置超时时间?的主要内容,如果未能解决你的问题,请参考以下文章

python操作word,关于win32com

Python / win32com / try和除/检查应用程序是否正在运行

python语音提示

如果某个任务正在任务管理器中运行,我如何在 python 中使用 pywin 或 win32com.client 检查?

使用 python win32com Outlook 清楚地记录阅读电子邮件功能

python win32gui模块下载