天天看点

PDMS.NET开发概述.NETPML + .NETSYSCOM

概述

PDMS 的.NET开发主要分以下两种:

  • .NET
  • PML + .NET

.NET

AVEVA公司提供了.NET的二次开发接口,以方便有C#开发经验的工程师可以快速的利用.NET框架对AVEVA的产品进行开发,如PDMS,MARINE等。

传统的PDMS开发主要利用PML语言,但AVEVA提供的PML对象库有限,如果想实现更多丰富的功能,使用PML开发就有很大的局限性。但利用.NET可以方便的使用各种第三方接口和类库,也可以完成与其他各种软件的集成,有利于数据的管理和维护。

PDMS.NET开发概述.NETPML + .NETSYSCOM

备注:

单纯的.NET开发和其他软件的.net开发,有相同的弊端。

  • 开发调试效率低
  • 插件的异常会导致PDMS的奔溃

IAddin接口

所有的AVEVA.NET插件都必须派生自IAddin接口,这也是AVEVA.NET插件与其他插件的不同之处。IAddin接口封装在

Aveva.ApplicationFramework.dl

l动态库中,因此在继承时,必须从

Aveva.ApplicationFramework

命名空间中进行引用,并且需要重写该接口。

该接口有2个属性和2个实例化方法,

IAddin

接口的原型声明如下:

string Description {get;}
string Name {get;}
void Start(ServiceManager  serviceManager);
void Stop();
           

开发DLL

PDMS只接受动态库的方式作为接口。

建立项目

建立一个命名为HelloAddin的项目。

项目引用

Aveva.ApplicationFramework、Aveva.ApplicationFramework.Presentation

两个动态库。这两个动态库主要封装了程序框架插件、发布服务、程序设置以及菜单栏和标题栏的管理、命令对象、本地资源文件、主程序窗口、状态栏、MDI(多文档程序)、用户控件等属性方法的类

// 1.引入命名空间
using  Aveva.ApplicationFramework;
using  Aveva.ApplicationFramework.Presentation;

// 2.声明命名空间
namespace HelloAddin
{
    // 3.声明类,必须继承IAddin接口
    Public class HelloAddin : IAddin
    {
        // 4.重写IAddin接口的属性及函数.此处Start()函数是程序的入口函数,类似于普通C#程序中的Main函数。
        public string Description
        {
            get {return "HelloAddin";}
        }

        public string Name
        {
            get {return "HelloAddin";}
        }
       
        public Void Start(ServiceManager serviceManager)
        {
            MessageBox.Show("Hello World");
        }
        public void Stop{}
    }
}

           

编译项目

生成动态库文件,HelloAddin.dll文件。目前PDMS的12.0和12.1均只能接受FrameWork 3.5的版本,请勿使用高版本,会导致PDMS加载失败。

PDMS操作

拷贝动态库

将动态库拷贝到PDMS的根目录下,也可以拷贝到其他子目录,只要修改启动文件即可。

修改启动文件

我们如果想将刚才开发的HelloAddin,绑定在PDMS的Design模块启动程序的话。只需要修改DesignAddin.xml文件即可。

这个文件在PDMS的根目录下,如果是绑定Draft、Paragon等其他模块,只要修改模块对应的xml文件即可。

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <string>ExplorerAddin</string>
  <string>HelloAddin</string>
</ArrayOfString>
           

如果不想把动态库放在根目录,可以建一个文件夹如:

mydevaddin

,放置我们的动态库。但xml需要同步改成

<string>mydevaddin/HelloAddin</string>

启动PDMS

运行界面如下图所示,当然这个程序并不能实现任何操作,仅仅是为了演示AVEVA.NET的实现过程。

PDMS.NET开发概述.NETPML + .NETSYSCOM

API概述

.NET开发主要是利用AVEVA提供的各种类和接口对PDMS各个数据层次进行访问,包括图形用户界面(GUI),数据库(DATABASE),几何库(Geometry)等。所有的这些类和接口都被封装在多个不同的dll(动态链接数据库)中,这些dll主要可分为以下几大类:

说明 dll文件 备注
CAF(common application framework interface)通用程序框架接口 Aveva.Application.Framework.dll 该动态库主要封装了程序框架插件、发布服务、程序设置管理等属性方法的类
CAF(common application framework interface)通用程序框架接口 Aveva.Application.Framework.Presentation.dll 该动态库主要封装了菜单栏和标题栏的管理以及命令对象、本地资源文件、主程序窗口、状态栏、MDI(多文档程序)以及用户控件等属性方法的类
数据库接口 Aveva.Pdms.Database.dll PDMSFilters.dll 该动态库主要封装了与数据库有关联的操作
几何库接口 AVEVA.Pdms.Geometry.dll 该动态库主要封装了与几何计算相关的类
共享接口 AVEVA.Pdms.Shared.dll
功能接口 AVEVA.Pdms.Utilities.dll 该动态库主要封装了消息、字符串、错误处理、追踪以及PML命令等类
图形接口 AVEVA.Pdms.Graphics.dll 该动态库主要封装了图形列表的相关类

PML + .NET

概述

PMLNET提供了在PDMS和.NET之间通信的服务。使用PMLNET可以实现以下三个功能:

  • PML调用.NET中定义的对象和方法。
  • PML在FORM中放置.NET中定义的控件。
  • 在.NET中调用PML对象和方法。
    PDMS.NET开发概述.NETPML + .NETSYSCOM
    数据匹配表:
PML .NET
real double
string string
bool bool
array hash table
object PMLNetCallable Class

PML调用.NET方法

C#开发

动态库加载

添加PMLNET引用,引用PMLNET.dll动态库,并引用命名空间。

using Aveva.PDMS.PMLNet

建立类库

按常规C#类库的开发方法运作,修改

AsemblyInfo.cs

配置文件。

PDMS.NET开发概述.NETPML + .NETSYSCOM

命名空间为

My.PMLNET

[PMLNetCallable()]
public class PMLNET
{
    [PMLNetCallable()]
    public PMLNET(){}

    [PMLNetCallable()]
    public void Assign(PMLNET that){}
   
    [PMLNetCallable()]
    public void MyMethod()
    {
        code
    }
}
           
  • 方法必须是公用的。
  • 类必须有一个声明无参数的构造函数。
  • 只能是类,不能是接口、结构等其他任意类型。
  • Assign方法是必须的。

PML调用

将编译好的DLL文件,拷贝到PDMS根目录以下。

加载动态库

import '动态库的名称' // 动态库加载后,无法卸载,必须重启PDMS才能更新,非常麻烦。

// 引入命名空间
using namespace '空间名'

!pmlnet = object PMLNET()
!pmlnet.MyMethod()
           

特殊说明

PML调用.NET方法,如果传递的数据类型是数组,则.NET中对应的是哈希表。如果用foeach循环的话,顺序是混乱的。table中的键必须将double型的变量显示转换为object型。

public bool Update(Hashtable table)
{
    for (int i = 1; i <= table.Count; i++)
    {
        string Guid = table[(object)double.Parse(i.ToString())].ToString();
    }
}
           

如果对数组的顺序不敏感的话,也可以使用foreach循环

foreach(DictionaryEntry de in  table)
{
    string str = de.Key.Tostring();
}
           

PML调用.NET控件

C#开发

用户控件的开发流程,和用户方法的类似。在新建的时候,不是选择Class,而是选择UserControl

[PMLNetCallable]
public partial class DateTimeControl : UserControl
{
    //构造函数
    [PMLNetCallable]
    public DateTimeControl()
    {
        InitializeComponent();
    }

    //固定写法
    [PMLNetCallable]
    public void Assign(DateTimeControl that)
    { }

    //获取dataTime的选择结果
    [PMLNetCallable]
    public String GetDatePick()
    {
        string date = this.dateTimePicker1.Value.Year + "-" + this.dateTimePicker1.Value.Month + "-" + this.dateTimePicker1.Value.Day;
        return date;
    }
}
           

此处control类的名称有要求,不能是Control后面加数字的写法。比如不能为UserControl1,否则在PML调用时,会出现语法错误。PML在调用.NET类时候,类名也不能末尾是数字。

PML调用

窗体定义

// .NET控件必须被放置在一个容器中
FRAME .frmTest '' 
    using namespace '命名空间' 
    container .excont PmlNetControl 'Contol'
exit

// 定义一个成员变量
member .dateTime is DateTimeControl
// 构造函数
using namespace '命名空间' 
!this.dateTime = object DateTimeControl()
// 调用Container控件的control方法,将其指定为成员变量的handle方法,这样PML就可以响应.NET的事件。
!this.excont.control = !this.dateTime.handle()
// 调用方法
!this.dateTime.GetDatePick()
// 调用事件,PML若想调用.NET的事件,必须先在.NET注册事件
!this.dateTime.AddEventHandler('OnPopup', !this, 'eventPML') // 注意事件方法是没有括号的。
           

SYSCOM

SYSCOM

也是一条PML命令,其用法和其他PML命令一样,只是其参数是Windows中的DOS命令。如在命令窗口中输入命令

syscom ‘dir’

,则可以在控制台窗口中显示出当前文件夹中的内容:

同理,输入

syscom ‘help’

则可以显示出常见DOS命令的使用说明:

由此可见,使用syscom相当于运行了一条DOS命令。因为DOS命令可以调用程序,如打开记事本,所以使用syscom也应该可以打开记事本。调用命令

syscom ‘notepad’

即可以了。

打开记事本后,可以看见PDMS程序处于等待状态。只有将记事本关闭,PDMS程序才恢复正常。如何使PDMS程序不用等待调用的程序是否执行完毕呢?PDMS中也提供了方法,那就是在程序名后加个

&

。如

syscom ‘calc&’

,就可以打开计算器程序而不用去等待是否将其关闭。

有了这条命令,把PDMS的扩展性又提高了,因为可以用syscom来调用Windows中的脚本即批处理文件。这样就可以用批处理来调用其他程序,由此摆脱因为AVEVA .NET(C#)开发时加载DLL后调试的不便,也可摆脱编程语言的限制,只要是一个程序都可以通过批处理来调用,即可以用C/C++或C#甚至VB来编写程序,再用通过syscom来调用。

继续阅读