Python COM事件处理被阻止

Python COM事件处理被阻止,python,events,com,handler,Python,Events,Com,Handler,我正在用Python实现COM,因为我必须在两个不同的软件(dSPACE HIL环境和Vector CANOE环境)之间进行交互caplscript&我想在事件发生时对dSPACE-HIL执行一些操作。目前我还没有实现任何线程 (1) 因此,第一个问题是,当我尝试使用一个简单的睡眠来确保测试执行在CANOE中完成时,执行不会发生,因为python睡眠正在阻止CANOE执行&而且我得到了pythoncom错误:每当环境变量改变时,调用COM方法的python错误。因此,只有在Python中的睡眠结

我正在用Python实现COM,因为我必须在两个不同的软件(dSPACE HIL环境和Vector CANOE环境)之间进行交互caplscript&我想在事件发生时对dSPACE-HIL执行一些操作。目前我还没有实现任何线程

(1) 因此,第一个问题是,当我尝试使用一个简单的睡眠来确保测试执行在CANOE中完成时,执行不会发生,因为python睡眠正在阻止CANOE执行&而且我得到了pythoncom错误:每当环境变量改变时,调用COM方法的python错误。因此,只有在Python中的睡眠结束后,CANOE执行才会开始&而且我在CANOE中看到以下弹出消息,说服务器正忙

当我使用消息框时,即测试完成后用户必须按下按钮执行正常。我想用其他机制(如睡眠)替换它。请告诉我如何解决此问题。我已将脚本粘贴在下面

class EnvironmentEvents:
    def __init__ ( self ) :
        print "Initializing Environment Event Class"
 
    def OnChange ( self , value ) :
        StopTestExecution = Value
        print '% 3.2f' % StopTestExecution
        print ( 'Environment Variable Value Changed' )
 
# # # # # # # # # # # # # # # # # # # INITIALIZE CONTROL DESK # # # # # # # # # # # 
MyControlDeskHandler = Controldesk_Handler. CONTROLDESK_HANDLER ()
 
# # # # # # # # # # # # # # # # # # # INITIALIZE CANOE # # # # # # # # # # # # # #  
MyCAN                = Dispatch ( 'CANoe.Application' )
MyCANMeasurement     = MyCAN. Measurement
MyCANEnvironment     = MyCAN. Environment . GetVariable ( "env_COM_BatteryVoltage" )
My events            = Dispatch WithEvents ( MyCANEnvironment , EnvironmentEvents )
 
Test Setup = MyCAN. Configuration . Test Setup
    TestEnvs = test setup. Test Environments
Testenv = TestEnvs. Item ( 1 )
Testenv. ExecuteAll ( )            
 
    ## Msgbox (0, "Test Completed", "info", 16) ## with a message box everything is working fine

    while ( StopTestExecution > 0 ):
            print '% 3.2f' % StopTestExecution
            Sleep ( 500 )    

我的想法是将CAPL中的事件变量值作为0发送,以停止执行。在此之前,必须继续循环。但这不起作用

(二)第二个问题是,当OnChange事件发生时,我想在dSPACE HIL控制台中更改一些内容。为此,我必须使用dSPACE提供的库。但问题是如何在Events类中访问此库及其方法。我尝试将dSPACE library对象和参数作为类的参数传递EnvironmentEvents,如下所示。现在我只是把它当作全球通用的&它工作得很好。但如果有更好的选择,我想避免它

class EnvironmentEvents:
    def __init__ ( self , ControlDeskhandler , Path ) :
        print "Initializing Environment Event Class"
        self . MyHandler = ControlDeskhandler
        self . MyPath = Path
 
    def OnChange ( self , value ) :
        StopTestExecution = Value
        print '% 3.2f' % StopTestExecution
        self . MyHandler . Write_Variable ( self . MyPath , Value )
        print ( 'Environment Variable Value Changed' )

    My events             = Dispatch WithEvents(MyCANEnvironment , Environment Events ( MyControlDeskHandler ,'Model Root/VOLTAGEOUT/ Value'))
 
Traceback ( most recent call load ) :
    .     File "C: \ P rogram Files (x86) \ C ommon Files \ d SPACE \ P ython25 \ l ib \ s ite-packages \ w in32com \ c lient \ __init__.py     " , line 304 , in Dispatch WithEvents
 result_class = new . classObj ( "COMEventClass" , ( disp_class , events_class , user_event_class ) , { "__setattr__": _event_setattr_ } )
TypeError : instance ( ) takes at most 2 arguments ( 3 givenName )
[ dbg ] >>>

请帮助我解决这些问题。如果您需要任何其他信息,请告诉我

Sleep的问题在于,它在睡眠时不会输出消息,COM需要处理消息才能工作。(
MessageBox
会泵送消息,所以它可以工作。)

这里的典型解决方案是使用
MsgWaitForMultipleObjectsEx
和消息泵。显然,
pythoncom
win32event
具有适当的包装器

需要一个手柄来等待;如果您需要等待特定的时间,那么最好创建一个可等待的计时器。奇怪的是,根据文档,
win32event
有,但没有
CreateWaitableTimer
。希望这是一个文档错误

无论如何,如果不需要特定的时间,可以使用创建win32事件。它可以是匿名事件;你所需要的只是等待。在OnChange处理程序中,可以设置事件

一旦有活动,您可以等待。原谅我可怕的巨蟒;这是C的音译

def WaitAndPumpMessagesWithTimeout(hWaitHandle, dwMilliseconds) :
{
    fContinue = TRUE;

    while (fContinue)
        dwWaitId = win32event.MsgWaitForMultipleObjectsEx(1, hWaitHandle, dwMilliseconds, win32event.QS_ALLINPUT, win32event.MWMO_INPUTAVAILABLE);
        if (dwWaitId == win32event.WAIT_OBJECT_0)
             return TRUE;
        elif (dwWaitId ==  WAIT_OBJECT_0 + 1)
            pythoncom.PumpWaitingMessages();
        elif (dwWaitId  == WAIT_TIMEOUT)
           return FALSE;
    return TRUE;
}

Sleep
的问题在于,它在睡眠时不会输出消息,COM需要处理消息才能工作。(MessageBox确实可以传输消息,所以它可以工作。)不幸的是,我对Python不够熟悉,无法告诉您在传输消息时如何睡眠。问题已解决。正如Eric指出的,睡眠不允许我发送消息&在睡眠之前使用pythoncom.PumpWaitingMessages()实现了这一神奇的功能。谢谢