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

    http://www.cnblogs.com/badnewfish/archive/2009/01/13/1374966.html

    本例下载/Files/badnewfish/OPC测试通过.rar

    转载申明

    申明:本文为转载,如需转载本文,请获取原文作者大尾巴狼啊的同意,谢谢合作!

    转自:大尾巴狼啊

    原文出处:http://www.cnblogs.com/xiaosacao/archive/2009/01/13/1374895.html

    前几天我就发布过这篇文章,可惜的是,发布后代码有的却看不到,后来我就删了,至今不明白什么原因- -!

    关于C++、VB来开发OPC客户端的资料网上有很多,但C#的至今没发现有多少。

    由于近期项目的需要,就开发了OPC客户端的一个模块。在我想来,程序员挺累的,原因我很累。所以我想大家也很累~~~嘿嘿。

    特别是刚接手OPC客户端开发的前几天,天天盯住显示器,百度、GOOGLE不停的搜索。每天早上醒来,眼睛都瑟瑟的。

    从事3年以上软件开发的朋友们,估计都会腰酸背痛吧!反正我是这样的。

    不说那么多废话了,贴上源码,让需要的同行看看吧,代码的质量并不高,就当做抛砖引玉吧!


    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的配置:

    有需要的留下EMAIL。。。。

    update:

    1、本文不提供例子代码下载。OPCDAAuto.dll可以在网上搜到的。

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

    a、本例采用的OPCDAAuto.dll版本是2.2.5.20。
    b、需要使用“regsvr32 /s OPCDAAuto.dll”命令在客户端计算机上注册这个程序集。
    c、首先保证客户机和服务器的网络是联通的。
  • 相关阅读:
    Ubuntu挂起后无法唤醒的问题以及解决方式
    两个比较给力的开源框架(1.头像选择,拍照,裁剪 2.自定义对话框)
    把APP演示做成GIF图
    单点触控与多点触控
    自定义imageView圆形图片
    自定义imageView圆形
    xmlBean类
    解析xml并展示数据(fragment)
    解析xml并展示数据(mainActivity)
    XStream解析xml代码
  • 原文地址:https://www.cnblogs.com/gmth/p/3145160.html
Copyright © 2011-2022 走看看