基于Python的COM库控制CANoe同时打开多个.cfg工程方法案例

一般CANoe如果要打开第二个工程时会覆盖第一个打开的工程,如果需要同时用脚本打开两个工程需要修改CAN.ini文件里的参数参数 将找个SingleCOMClient=0改为 “SingleCOMClient=1“即可。
这个CAN.ini文件在C:\ProgramData\Vector\CANoe\17 (x64)目录下 可以CMD下执行这个命名:

dir C:\\ProgramData\\CAN.ini /S /B
1. 下面是我通过python代码去修改这个CAN.ini文件的代码:
import subprocess
import sys


def find_can_ini():
    cmd = 'dir C:\\ProgramData\\CAN.ini /S /B'
    result = subprocess.run(cmd, capture_output=True, text=True, shell=True)
    output = result.stdout.strip()
    if output:
        return output.split('\n')[0]  # 返回第一个找到的结果
    else:
        raise FileNotFoundError("CAN.ini 文件未找到")


def modify_can_ini(file_path, value):
    with open(file_path, 'r') as file:
        lines = file.readlines()

    with open(file_path, 'w') as file:
        for line in lines:
            if 'SingleCOMClient=' in line:
                line = line.replace('SingleCOMClient=1', f'SingleCOMClient={value}')
                line = line.replace('SingleCOMClient=0', f'SingleCOMClient={value}')
            file.write(line)


if __name__ == '__main__':
    if len(sys.argv) != 2 or sys.argv[1] not in ['0', '1']:
        print("Usage: python test.py <value>")
        print("<value> should be 0 or 1")
        sys.exit(1)

    value = int(sys.argv[1])
    try:
        can_ini_path = find_can_ini()
        print(f"CAN.ini 文件的绝对路径是: {can_ini_path}")
        modify_can_ini(can_ini_path, value)
        print(f"已成功修改 {can_ini_path} 文件中的 SingleCOM 参数为 {value}")
    except FileNotFoundError as e:
        print(e)

    print("Finished")

上面代码就可以将CAN.ini文件参数SingleCOMClient改为1

; 允许只有一个单一客户端连接到应用程序
; 每个进一步的客户端如果创建一个类的实例
; 将会启动一个新的应用程序实例。
; 请注意,这将意味着许多其他COM客户端可能无法正常工作,
; 并且使用ActiveX或.NET面板加载配置可能会导致
; 递归启动更多的应用程序实例。
SingleCOMClient=0

下面就可以打开多个CANoe工程了

2. 打开第一个工程,源码如下:
import sys
import json
import time
import win32com.client
import subprocess

app = win32com.client.Dispatch('CANoe.Application')
Measurement = app.Measurement


def get_canoe_pid():
    # 执行 tasklist 命令
    result = subprocess.run(['tasklist'], capture_output=True, text=True)
    # 解析输出
    for line in result.stdout.splitlines():
        if 'CANoe64.exe' in line:
            # 提取 PID
            parts = line.split()
            pid = int(parts[1])  # PID 通常是第二个部分
            return pid
    return None

def RTServerConnect():
    app.Configuration.DistributedMode.Connect()
    app.Configuration.Save()

def RTServerDisconnect():
    app.Configuration.DistributedMode.Disconnect()
    app.Configuration.Save()


def getRTServerResult():
    RTServer = app.Configuration.DistributedMode.RTServer
    if RTServer:
        print(RTServer)
        return RTServer
    print(RTServer)
    return None


def setRTServerEnable(RTServer):
    app.Configuration.DistributedMode.RTServer = RTServer
    print("success!!! ")


def setRTServerDisenable():
    # self.App.Configuration.DistributedMode.RTServer = "169.254.80.10"
    app.Configuration.DistributedMode.RTServer = ""


def link_and_start_app(link_cfg):
    app.Open(link_cfg)
    time.sleep(20)
    if getRTServerResult():
        setRTServerDisenable()
    Measurement.Start()

    pid = get_canoe_pid()
    CANoe_PID = pid
    with open("ProcessPID.txt", "w") as json_file:
        json.dump(CANoe_PID, json_file)

if __name__ == "__main__":
    j_workspace = sys.argv[1]
    link_cfg = r'%s\ResourceTest\T1_link\T1_link.cfg' % j_workspace
    link_and_start_app(link_cfg)
    print("finished")
    
3. 打开第二个CANoe工程,源码如下
import sys
import time
import win32com.client
from Common import RTServerIP

app = win32com.client.Dispatch('CANoe.Application')
Measurement = app.Measurement


def RTServerConnect():
    app.Configuration.DistributedMode.Connect()


def RTServerDisconnect():
    app.Configuration.DistributedMode.Disconnect()


def getRTServerResult():
    RTServer = app.Configuration.DistributedMode.RTServer
    if RTServer:
        print(RTServer)
        return RTServer
    print(RTServer)
    return None

def setRTServerEnable(deviceID):
    app.Configuration.DistributedMode.RTServer = RTServerIP[f"{deviceID}"]
    # app.Configuration.DistributedMode.RTServer = "192.169.2.90"
    app.Configuration.Save()
    print("success!!! ")

def setRTServerDisenable():
    # self.App.Configuration.DistributedMode.RTServer = "169.254.80.10"
    app.Configuration.DistributedMode.RTServer = ""

def no_live_and_start_app(no_live_cfg, Device_ID):

    app.Open(no_live_cfg)
    time.sleep(10)
    # RTServer = getRTServerResult()
    setRTServerEnable(Device_ID)
    time.sleep(20)
    Measurement.Start()
# #
if __name__ == '__main__':
    j_workspace = sys.argv[1]
    device_ID = sys.argv[2]
    no_live_cfg = r'%s\ResourceTest\NoRX\NoRx.cfg' % j_workspace
    no_live_and_start_app(no_live_cfg, device_ID)
    print("finished")
4. 两个参数的区别

SingleCOMClient=0 和 SingleCOMClient=1 是配置项,用于控制应用程序的客户端连接行为。它们的区别如下:

1. SingleCOMClient=0

允许多个客户端连接: 设置为0表示允许多个客户端同时连接到应用程序。
实例化行为: 每当一个新的客户端创建一个类的实例时,应用程序不会限制它们,而是允许每个客户端启动自己的应用程序实例。
潜在问题: 可能导致资源竞争、状态不一致或其他COM客户端无法正常工作,因为多个实例可能会相互干扰。

2. SingleCOMClient=1

限制为单一客户端连接: 设置为1表示只允许一个客户端连接到应用程序。
实例化行为: 如果有其他客户端尝试连接或创建类的实例,应用程序将拒绝这些请求,或者启动新的应用程序实例。
提高稳定性: 这种设置可以减少由于多个实例同时运行而导致的潜在问题,确保应用程序的状态和资源管理更加一致。

总结
  • SingleCOMClient=0: 允许多个客户端连接,可能导致多个应用程序实例同时运行,存在潜在的资源和状态管理问题。
  • SingleCOMClient=1: 限制为单一客户端连接,确保应用程序的稳定性和一致性,避免多个实例之间的干扰。

选择哪个设置取决于应用程序的需求和使用场景。如果需要支持多个客户端并且能够处理潜在的冲突,可以选择0;如果希望确保应用程序的稳定性和一致性,则应选择1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值