通过 COM/ActiveX 从 Python 控制项目内部的 VI

Posted

技术标签:

【中文标题】通过 COM/ActiveX 从 Python 控制项目内部的 VI【英文标题】:Controlling VI inside of Project from Python via COM/ActiveX 【发布时间】:2022-01-03 21:37:44 【问题描述】:

来自NI-Site:

labview = win32com.client.Dispatch("Labview.Application")
VI = labview.getvireference(r'c:\TEMP\ctrl\ctrl.vi')
print(f'Name: VI.Name')
print(VI.getcontrolvalue('main'))

只要我的 VI 不在项目中,它就可以正常工作。但是,我在项目中有一个正在运行的 VI,并且想从 python 读取/写入控制值。没有错误,但 python 读取/写入项目外部的 VI 的单独实例。我可以修改 VI 的路径,以便 python 访问项目中的实例吗?

如何重现:

    Python 脚本

    from icecream import ic
    import win32com.client
    import time
    import numpy as np
    
    class LabView():
        def __init__(self,vi):
            self.LabVIEW    = win32com.client.Dispatch("Labview.Application")
            self.VI         = self.LabVIEW.getvireference(vi)
        def set_potential(self,potential):
            ic(potential)
            self.VI.SetControlValue("Set Potential",potential)  
    
    
    vi = r'C:\path...\testProject\test.vi'
    lab = LabView(vi)
    
    
    while True:
        lab.set_potential(np.random.uniform(-2,2))
        time.sleep(3)
    
    
    
    

    Place VI inside of project

    在项目外打开并运行 VI 并启动 python 脚本 -> 工作

    从 Project Explorer 打开并运行 VI 并启动 python 脚本 -> 不起作用

【问题讨论】:

您能分享一下您的项目结构吗?我进行了快速测试——就我而言,一切正常。我有 VI,它是项目的一部分。 VI 运行时,python 代码可以很好地读取指标值。 我已经添加了结构的图片。我可以同时打开同一个VI的两个实例,一个在项目内,一个在项目外。 Python 如何知道它应该引用哪个实例? 我相信Python并不关心VI是从哪里启动的。我做了简单的测试——创建项目,添加VI,保存项目。从项目中打开 VI,启动它 - 然后执行 python 脚本。它准确地捕捉到了那个特定的 VI。你怎么知道,python 读/写了 VI 的另一个实例? 我有一个小脚本,每秒将控制值设置为随机值。当我在项目外部打开 VI 时,我可以看到值发生了变化(运行时以及不运行时)。然后我关闭这个VI并打开项目。从 Project Explorer 启动 VI,值没有改变。 @kosist 你介意分享你的简单测试吗?我试图重新创建它,它和我的主项目有同样的问题 【参考方案1】:

您可以考虑构建一个可以通过G-CLI tool(目前仅适用于Windows)调用的vi,然后通过python 的命令行进行交互。

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review【参考方案2】:

这应该让您对如何做到这一点有所了解。我已经成功了。您必须使用 OpenProject active x 方法来获取对项目的引用,然后使用 project.Application 在项目的上下文中获取对应用程序的引用。从那时起,它的工作方式类似于与非项目 VI 进行通信,即用 proj.Application 替换 win32com.client.Dispatch("Labview.Application") 引用

class LabView():
    def __init__(self,project_path=''): #vi path 
        self.LabVIEW_Top    = win32com.client.Dispatch("Labview.Application")
        self.LabVIEW=self.LabVIEW_Top #init as if there is no project
        if project_path !='' :# project path was provided
            self.LabVIEW_Top._FlagAsMethod('OpenProject')
            proj=self.LabVIEW_Top.OpenProject(project_path)
            self.LabVIEW=proj.Application #over ride to project application

【讨论】:

以上是关于通过 COM/ActiveX 从 Python 控制项目内部的 VI的主要内容,如果未能解决你的问题,请参考以下文章

邮件远控电脑MCC-python实现

Python 获取一个字典的子集

将Python远控隐藏在文档图片中的行动分析

将Python远控隐藏在文档图片中的行动分析

Python 千猫图,简单技术满足你的收集控

Python 千猫图,简单技术满足你的收集控