Python调用CANoe时出现COM错误的解决方法咨询
问题描述
编写了一个用于打开CANoe并启动测量的Python脚本,已成功启动CANoe,但在调用App.Open加载配置文件时触发com_error,错误信息如下:
Exception has occurred: com_error (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147467259), None) File "C:\Users\randomuser\AppData\Local\Temp\gen_py\3.8\7F31DEB0-5BCC-11D3-8562-00105A3E017Bx0x1x55.py", line 538, in Open return self._oleobj_.InvokeTypes(7, LCID, 1, (24, 0), ((8, 1), (11, 17), (11, 17)),config File "C:\SMP\S_T\Py\ST.py", line 36, in Load self.App.Open(cfg) File "C:\SMP\S_T\Py\ST.py", line 141, in <module> app.Load('CANoeConfig\PythonBasicEmpty.cfg')
已尝试删除自动生成的gen_py文件,但问题仍未解决,代码如下:
import time, os, msvcrt from win32com.client import * from win32com.client.connect import * def DoEvents(): pythoncom.PumpWaitingMessages() time.sleep(.1) def DoEventsUntil(cond): while not cond(): DoEvents() class CanoeSync(object): """Wrapper class for CANoe Application object""" Started = False Stopped = False ConfigPath = "" def __init__(self): app = DispatchEx('CANoe.Application') app.Configuration.Modified = False ver = app.Version print('Loaded CANoe version ', ver.major, '.', ver.minor, '.', ver.Build, '...', sep='') self.App = app self.Measurement = app.Measurement self.Running = lambda : self.Measurement.Running self.WaitForStart = lambda: DoEventsUntil(lambda: CanoeSync.Started) self.WaitForStop = lambda: DoEventsUntil(lambda: CanoeSync.Stopped) WithEvents(self.App.Measurement, CanoeMeasurementEvents) def Load(self, cfgPath): # current dir must point to the script file cfg = os.path.join(os.curdir, cfgPath) cfg = os.path.abspath(cfg) print('Opening: ', cfg) self.ConfigPath = os.path.dirname(cfg) self.Configuration = self.App.Configuration self.App.Open(cfg) def LoadTestSetup(self, testsetup): self.TestSetup = self.App.Configuration.TestSetup path = os.path.join(self.ConfigPath, testsetup) testenv = self.TestSetup.TestEnvironments.Add(path) testenv = CastTo(testenv, "ITestEnvironment2") # TestModules property to access the test modules self.TestModules = [] self.TraverseTestItem(testenv, lambda tm: self.TestModules.append(CanoeTestModule(tm))) def LoadTestConfiguration(self, testcfgname, testunits): """ Adds a test configuration and initialize it with a list of existing test units """ tc = self.App.Configuration.TestConfigurations.Add() tc.Name = testcfgname tus = CastTo(tc.TestUnits, "ITestUnits2") for tu in testunits: tus.Add(tu) # TestConfigs property to access the test configuration self.TestConfigs = [CanoeTestConfiguration(tc)] def Start(self): if not self.Running(): self.Measurement.Start() self.WaitForStart() def Stop(self): if self.Running(): self.Measurement.Stop() self.WaitForStop() ''' def RunTestModules(self): """ starts all test modules and waits for all of them to finish""" # start all test modules for tm in self.TestModules: tm.Start() # wait for test modules to stop while not all([not tm.Enabled or tm.IsDone() for tm in app.TestModules]): DoEvents()''' def RunTestConfigs(self): """ starts all test configurations and waits for all of them to finish""" # start all test configurations for tc in self.TestConfigs: tc.Start() # wait for test modules to stop while not all([not tc.Enabled or tc.IsDone() for tc in app.TestConfigs]): DoEvents() def TraverseTestItem(self, parent, testf): for test in parent.TestModules: testf(test) for folder in parent.Folders: found = self.TraverseTestItem(folder, testf) class CanoeMeasurementEvents(object): """Handler for CANoe measurement events""" def OnStart(self): CanoeSync.Started = True CanoeSync.Stopped = False print("< measurement started >") def OnStop(self) : CanoeSync.Started = False CanoeSync.Stopped = True print("< measurement stopped >") class CanoeTestModule: """Wrapper class for CANoe TestModule object""" def __init__(self, tm): self.tm = tm self.Events = DispatchWithEvents(tm, CanoeTestEvents) self.Name = tm.Name self.IsDone = lambda: self.Events.stopped self.Enabled = tm.Enabled def Start(self): if self.tm.Enabled: self.tm.Start() self.Events.WaitForStart() class CanoeTestConfiguration: """Wrapper class for a CANoe Test Configuration object""" def __init__(self, tc): self.tc = tc self.Name = tc.Name self.Events = DispatchWithEvents(tc, CanoeTestEvents) self.IsDone = lambda: self.Events.stopped self.Enabled = tc.Enabled def Start(self): if self.tc.Enabled: self.tc.Start() self.Events.WaitForStart() class CanoeTestEvents: """Utility class to handle the test events""" def __init__(self): self.started = False self.stopped = False self.WaitForStart = lambda: DoEventsUntil(lambda: self.started) self.WaitForStop = lambda: DoEventsUntil(lambda: self.stopped) def OnStart(self): self.started = True self.stopped = False print("<", self.Name, " started >") def OnStop(self, reason): self.started = False self.stopped = True print("<", self.Name, " stopped >") # ----------------------------------------------------------------------------- # main # ----------------------------------------------------------------------------- app = CanoeSync() # loads the sample configuration app.Load('CANoeConfig\PythonBasicEmpty.cfg') # add test modules to the configuration #app.LoadTestSetup('TestEnvironments\Test Environment.tse') # add a test configuration and a list of test units app.LoadTestConfiguration('TestConfiguration', ['C:\SMP\S_T\repo\ST\example.vtuexe']) # start the measurement app.Start() # runs the test modules app.RunTestModules() # runs the test configurations app.RunTestConfigs() # wait for a keypress to end the program print("Press any key to exit ...") while not msvcrt.kbhit(): DoEvents() # stops the measurement app.Stop()
请问该如何修复这个问题?
解决方法
1. 修复路径转义问题
Python中反斜杠是转义字符,直接写'CANoeConfig\PythonBasicEmpty.cfg'会导致路径解析错误,改成以下两种方式之一:
- 使用原始字符串:
r'CANoeConfig\PythonBasicEmpty.cfg' - 使用正斜杠:
'CANoeConfig/PythonBasicEmpty.cfg'
同样,LoadTestConfiguration中的路径'C:\SMP\S_T\repo\ST\example.vtuexe'也要做相同修改。
2. 验证配置文件路径有效性
检查Load方法中打印的cfg路径,确认该路径下的.cfg文件确实存在,文件名、文件夹名没有拼写错误(注意大小写)。
3. 调整Configuration.Modified的设置时机
在CanoeSync的__init__方法中,刚启动CANoe就设置app.Configuration.Modified = False会引发问题——此时未加载任何配置,该属性处于未初始化状态。把这行代码移到Load方法中,加载完配置后再设置:
def Load(self, cfgPath): cfg = os.path.join(os.curdir, cfgPath) cfg = os.path.abspath(cfg) print('Opening: ', cfg) self.App.Open(cfg) # 先加载配置 self.Configuration = self.App.Configuration self.Configuration.Modified = False # 加载完成后再设置 self.ConfigPath = os.path.dirname(cfg)
4. 以管理员身份运行脚本
CANoe加载配置时可能需要系统权限,右键点击Python脚本或运行脚本的IDE,选择“以管理员身份运行”。
5. 检查CANoe版本与COM接口兼容性
如果安装的CANoe版本较新,尝试用EnsureDispatch代替DispatchEx初始化CANoe对象,确保COM接口版本匹配:
app = EnsureDispatch('CANoe.Application')
也可以删除gen_py文件夹后重启脚本,让系统重新生成适配当前CANoe版本的COM封装文件。
6. 关闭后台CANoe进程
任务管理器中结束所有CANoe相关进程,避免多个实例冲突导致配置加载失败。
内容的提问来源于stack exchange,提问作者user23057750
相关产品推荐
相关产品推荐

