zoukankan      html  css  js  c++  java
  • 【转】(C#)OPC客户端源码

    原文:https://www.cnblogs.com/badnewfish/archive/2009/04/11/1374966.html

    1、枚举本地服务器

    2、获取服务器信息

    3、列出了服务器上Tag

    4、可以设置组的属性

    5、读写功能

    6、可进行远程连接(DCOM需配置)

    先看图:

    引用类库:

    OPC服务器:

    开发工具:

    当前环境:

     

    源码:

    复制代码

    ///摘要
    ///程式使用C#.NET 2005 编写
    ///引用类库OPCDAAuto.dll
    ///OPCServer采用KEPWare
    ///在windows xp sp2、sp3、windows 2003上测试通过
    ///完成于:2008年12月31日
    ///测试于:2009年01月05日
    ///
    ///作者:潇洒草
    ///Email:zhkai868@163.com
    ///QQ:44649029
    /// 
    ///如分发,请保留此摘要。
    ///鄙视那些拿代码当宝贝的人,鄙视那些你不拿源码换就不稀罕你的人,鄙视那些自私的人。
    ///别人看到你的代码,你能死啊?对你有多大威胁啊?强烈鄙视~~~
    ///如果你是这样的人,赶紧关了。。偶不欢迎。。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Collections;
    using OPCAutomation;

    namespace OPC测试通过
    {
        public partial class MainFrom : Form
        {
            public MainFrom()
            {
                InitializeComponent();
            }

            #region 私有变量
            /// <summary>
            /// OPCServer Object
            /// </summary>
            OPCServer KepServer;
            /// <summary>
            /// OPCGroups Object
            /// </summary>
            OPCGroups KepGroups;
            /// <summary>
            /// OPCGroup Object
            /// </summary>
            OPCGroup KepGroup;
            /// <summary>
            /// OPCItems Object
            /// </summary>
            OPCItems KepItems;
            /// <summary>
            /// OPCItem Object
            /// </summary>
            OPCItem KepItem;
            /// <summary>
            /// 主机IP
            /// </summary>
            string strHostIP = "";
            /// <summary>
            /// 主机名称
            /// </summary>
            string strHostName = "";
            /// <summary>
            /// 连接状态
            /// </summary>
            bool opc_connected = false;
            /// <summary>
            /// 客户端句柄
            /// </summary>
            int itmHandleClient = 0;
            /// <summary>
            /// 服务端句柄
            /// </summary>
            int itmHandleServer = 0;
            #endregion

            #region 方法
            /// <summary>
            /// 枚举本地OPC服务器
            /// </summary>
            private void GetLocalServer()
            {
                //获取本地计算机IP,计算机名称
                IPHostEntry IPHost = Dns.Resolve(Environment.MachineName);
                if (IPHost.AddressList.Length > 0)
                {
                    strHostIP = IPHost.AddressList[0].ToString();
                }
                else
                {
                    return;
                }
                //通过IP来获取计算机名称,可用在局域网内
                IPHostEntry ipHostEntry = Dns.GetHostByAddress(strHostIP);
                strHostName=ipHostEntry.HostName.ToString();

                //获取本地计算机上的OPCServerName
                try
                {
                    KepServer = new OPCServer();
                    object serverList = KepServer.GetOPCServers(strHostName);

                    foreach (string turn in (Array)serverList)
                    {
                        cmbServerName.Items.Add(turn);
                    }

                    cmbServerName.SelectedIndex = 0;
                    btnConnServer.Enabled = true;
                }
                catch(Exception err)
                {
                    MessageBox.Show("枚举本地OPC服务器出错:"+err.Message,"提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                }

            }
            /// <summary>
            /// 创建组
            /// </summary>
            private bool CreateGroup()
            {
                try
                {
                    KepGroups = KepServer.OPCGroups;
                    KepGroup = KepGroups.Add("OPCDOTNETGROUP");
                    SetGroupProperty();
                    KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
                    KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
                    KepItems = KepGroup.OPCItems;
                }
                catch (Exception err)
                {
                    MessageBox.Show("创建组出现错误:"+err.Message,"提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                    return false;
                }
                return true;
            }
            /// <summary>
            /// 设置组属性
            /// </summary>
            private void SetGroupProperty()
            {
                KepServer.OPCGroups.DefaultGroupIsActive =Convert.ToBoolean(txtGroupIsActive.Text);
                KepServer.OPCGroups.DefaultGroupDeadband = Convert.ToInt32(txtGroupDeadband.Text);
                KepGroup.UpdateRate = Convert.ToInt32(txtUpdateRate.Text);
                KepGroup.IsActive = Convert.ToBoolean(txtIsActive.Text);
                KepGroup.IsSubscribed =Convert.ToBoolean(txtIsSubscribed.Text);
            }
            /// <summary>
            /// 列出OPC服务器中所有节点
            /// </summary>
            /// <param name="oPCBrowser"></param>
            private void RecurBrowse(OPCBrowser oPCBrowser)
            {
                //展开分支
                oPCBrowser.ShowBranches();
                //展开叶子
                oPCBrowser.ShowLeafs(true);
                foreach (object turn in oPCBrowser)
                {
                    listBox1.Items.Add(turn.ToString());
                }
            }
            /// <summary>
            /// 获取服务器信息,并显示在窗体状态栏上
            /// </summary>
            private void GetServerInfo()
            {
                tsslServerStartTime.Text ="开始时间:"+ KepServer.StartTime.ToString()+"    ";
                tsslversion.Text ="版本:"+ KepServer.MajorVersion.ToString() + "." + KepServer.MinorVersion.ToString()+"."+KepServer.BuildNumber.ToString();
            }
            /// <summary>
            /// 连接OPC服务器
            /// </summary>
            /// <param name="remoteServerIP">OPCServerIP</param>
            /// <param name="remoteServerName">OPCServer名称</param>
            private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
            {
                try
                {
                    KepServer.Connect(remoteServerName, remoteServerIP);

                    if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
                    {
                        tsslServerState.Text = "已连接到-" + KepServer.ServerName + "   ";
                    }
                    else
                    {
                        //这里你可以根据返回的状态来自定义显示信息,请查看自动化接口API文档
                        tsslServerState.Text = "状态:" + KepServer.ServerState.ToString() + "   ";
                    }
                }
                catch (Exception err)
                {
                    MessageBox.Show("连接远程服务器出现错误:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return false;
                }
                return true;
            }
            #endregion

            #region 事件
            /// <summary>
            /// 写入TAG值时执行的事件
            /// </summary>
            /// <param name="TransactionID"></param>
            /// <param name="NumItems"></param>
            /// <param name="ClientHandles"></param>
            /// <param name="Errors"></param>
            void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
            {
                lblState.Text = "";
                for (int i = 1; i <= NumItems; i++)
                {
                    lblState.Text += "Tran:" + TransactionID.ToString() + "   CH:" + ClientHandles.GetValue(i).ToString() + "   Error:" + Errors.GetValue(i).ToString();
                }
            }
            /// <summary>
            /// 每当项数据有变化时执行的事件
            /// </summary>
            /// <param name="TransactionID">处理ID</param>
            /// <param name="NumItems">项个数</param>
            /// <param name="ClientHandles">项客户端句柄</param>
            /// <param name="ItemValues">TAG值</param>
            /// <param name="Qualities">品质</param>
            /// <param name="TimeStamps">时间戳</param>
            void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
            {
                //为了测试,所以加了控制台的输出,来查看事物ID号
                //Console.WriteLine("********"+TransactionID.ToString()+"*********");
                for (int i = 1; i <= NumItems; i++)
                {
                    this.txtTagValue.Text = ItemValues.GetValue(i).ToString();
                    this.txtQualities.Text = Qualities.GetValue(i).ToString();
                    this.txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
                }
            }
            /// <summary>
            /// 选择列表项时处理的事情
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                try
                {
                    if (itmHandleClient != 0)
                    {
                        this.txtTagValue.Text = "";
                        this.txtQualities.Text ="";
                        this.txtTimeStamps.Text = "";

                        Array Errors;
                        OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
                        //注:OPC中以1为数组的基数
                        int[] temp = new int[2] { 0, bItem.ServerHandle };
                        Array serverHandle = (Array)temp;
                        //移除上一次选择的项
                        KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
                    }
                    itmHandleClient = 1234;
                    KepItem = KepItems.AddItem(listBox1.SelectedItem.ToString(), itmHandleClient);
                    itmHandleServer = KepItem.ServerHandle;
                }
                catch(Exception err)
                {
                    //没有任何权限的项,都是OPC服务器保留的系统项,此处可不做处理。
                    itmHandleClient = 0;
                    txtTagValue.Text = "Error ox";
                    txtQualities.Text = "Error ox";
                    txtTimeStamps.Text = "Error ox";
                    MessageBox.Show("此项为系统保留项:"+err.Message,"提示信息");
                }
            }
            /// <summary>
            /// 载入窗体时处理的事情
            /// </summary>
            private void MainFrom_Load(object sender, EventArgs e)
            {
                GetLocalServer();
            }
            /// <summary>
            /// 关闭窗体时处理的事情
            /// </summary>
            private void MainFrom_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (!opc_connected)
                {
                    return;
                }

                if (KepGroup != null)
                {
                    KepGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
                }

                if (KepServer != null)
                {
                    KepServer.Disconnect();
                    KepServer = null;
                }

                opc_connected = false;
            }
            /// <summary>
            /// 【按钮】设置
            /// </summary>
            private void btnSetGroupPro_Click(object sender, EventArgs e)
            {
                SetGroupProperty();
            }
            /// <summary>
            /// 【按钮】连接OPC服务器
            /// </summary>
            private void btnConnLocalServer_Click(object sender, EventArgs e)
            {
                try
                {
                    if (!ConnectRemoteServer(txtRemoteServerIP.Text,cmbServerName.Text))
                    {
                        return;
                    }

                    btnSetGroupPro.Enabled = true;

                    opc_connected = true;

                    GetServerInfo();

                    RecurBrowse(KepServer.CreateBrowser());

                    if (!CreateGroup())
                    {
                        return;
                    }
                }
                catch (Exception err)
                {
                    MessageBox.Show("初始化出错:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            /// <summary>
            /// 【按钮】写入
            /// </summary>
            private void btnWrite_Click(object sender, EventArgs e)
            {
                OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
                int[] temp = new int[2] { 0, bItem.ServerHandle };
                Array serverHandles=(Array)temp;
                object[] valueTemp = new object[2] {"",txtWriteTagValue.Text };
                Array values=(Array)valueTemp;
                Array Errors;
                int cancelID;
                KepGroup.AsyncWrite(1,ref serverHandles,ref values,out Errors, 2009,out cancelID);
                //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
                GC.Collect();
            }
            #endregion
        }
    }
    复制代码

    自动化接口API文档:

    关于DCOM的配置:

    update:

    1、本文中是在2009年元月写的,可能有很多过时之处,现在最新(2014年)的OPC官网已经有关于C#调用的例子:http://www.opcfoundation.org/default.aspx/classicdownloads.asp?MID=Developers

    2、客户端连接OPC服务器注意事项:

    a、本例采用的OPCDAAuto.dll版本是2.2.5.20。
    b、需要使用“regsvr32 /s OPCDAAuto.dll”命令在客户端计算机上注册这个程序集。
    c、首先保证客户机和服务器的网络是联通的。
  • 相关阅读:
    HEVC软件记录
    怪诞行为学
    docker学习实践之路[第一站]环境安装
    centos系统(ssh)登录缓慢(输入账户密码后需要等待若干时间)
    CentOS7.x编译安装nginx,实现HTTP2
    vs 2017 IIS EXPRESS 增加局域网访问
    nginx在centos 7中源码编译安装【添加grpc的支持】
    docker学习实践之路[第五站]mysql镜像应用
    docker学习实践之路[第四站]利用pm2镜像部署node应用
    docker学习实践之路[第三站]node站点部署
  • 原文地址:https://www.cnblogs.com/luofuxian/p/9103316.html
Copyright © 2011-2022 走看看