资源描述
【转】(C#)OPC客户端源码
转载申明
申明:本文为转载,如需转载本文,请获取原文作者大尾巴狼啊的同意,谢谢合作!
转自:大尾巴狼啊
原文出处:
前几天我就发布过这篇文章,可惜的是,发布后代码有的却看不到,后来我就删了,至今不明白什么原因- -!
关于C++、VB来开发OPC客户端的资料网上有很多,但C#的至今没发现有多少。
由于近期项目的需要,就开发了OPC客户端的一个模块。在我想来,程序员挺累的,原因我很累。所以我想大家也很累~~~嘿嘿。
特别是刚接手OPC客户端开发的前几天,天天盯住显示器,百度、GOOGLE不停的搜索。每天早上醒来,眼睛都瑟瑟的。
从事3年以上软件开发的朋友们,估计都会腰酸背痛吧!反正我是这样的。
不说那么多废话了,贴上源码,让需要的同行看看吧,代码的质量并不高,就当做抛砖引玉吧!
1、枚举本地服务器
2、获取服务器信息
3、列出了服务器上Tag
4、可以设置组的属性
5、读\写功能
6、可进行远程连接(DCOM需配置)
先看图:
引用类库:
OPC服务器:
开发工具:
当前环境:
源码:
Code
///摘要
///程式使用C#.NET 2005 编写
///引用类库OPCDAAuto.dll
///OPCServer采用KEPWare
///在windows xp sp2、sp3、windows 2003上测试通过
///完成于:2008年12月31日
///测试于:2009年01月05日
///
///作者:潇洒草
///Email:zhkai868@
///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、例子代码下载地址:点击下载
2、客户端连接OPC服务器注意事项:
a、本例采用的OPCDAAuto.dll版本是2.2.5.20。
b、需要使用“regsvr32 /s OPCDAAuto.dll”命令在客户端计算机上注册这个程序集。
c、首先保证客户机和服务器的网络是联通的。
Tag标签: opc,OPC客户端,C#开发OPC,OPC远程访问,OPC服务器远程访问,OPC源码
badnewfish
关注 - 0
粉丝 - 0
关注博主
4
0
0
(请您对文章做出评价)
« 上一篇:异步Socket【转】
» 下一篇:【转】c# xml添加 删除 修改数据
posted on 2009-01-13 16:10 badnewfish 阅读(3374) 评论(52) 编辑 收藏 所属分类: OPC
评论
1605778
#1楼 219.239.36.* 回复 引用
想要文档和源码,谢谢!
2009-01-13 16:26 | 小毛[未注册用户]
#2楼 221.232.69.* 回复 引用
想要文档和源码,请问下timestemp能作为item的value改变的依据么?
2009-01-22 13:27 | lordfish_sl[未注册用户]
#3楼[楼主] 回复 引用 查看
@lordfish_sl
转的文章,你自己研究一下!
2009-02-02 09:49 | badnewfish
#4楼 58.49.110.* 回复 引用
楼主发份资料给我,谢谢,赞共享精神,谁说java才开源:)
2009-02-04 12:03 | tensai[未注册用户]
#5楼[楼主] 回复 引用 查看
@tensai
你的邮件地址发不出去
2009-02-04 17:46 | badnewfish
#6楼 159.226.77.* 回复 引用
楼主我也需要文档和源码!谢谢!
2009-02-09 09:50 | HHH[未注册用户]
#7楼[楼主] 回复 引用 查看
@HHH
老大,你的阅读能力有限啊!
2009-02-10 09:29 | badnewfish
#8楼 221.215.132.* 回复 引用
你好博主: 可以发送给我一份文档和代码吗? 谢谢!
我的email是:@
2009-02-19 14:44 | guojian[未注册用户]
#9楼 61.183.133.* 回复 引用
你好,想要你的代码和文档,谢谢
2009-02-27 09:07 | zhippy[未注册用户]
#10楼 60.174.132.* 回复 引用
zhenghan01@
需要代码和文档,谢谢楼主
2009-02-27 23:38 | zhenghan[未注册用户]
#11楼 221.223.47.* 回复 引用
谢谢楼主 我的课题也需要代码和文档
30514gyf@
2009-02-28 01:15 | siren[未注册用户]
#12楼 58.218.185.* 回复 引用
博主你好!
自动化接口API文档和关于DCOM的配置:能发一份给我么?
最近在研究OPC,麻烦你了,不感激!
邮箱:yantongdong@
2009-03-02 11:09 | yantongdong[未注册用户]
#13楼 219.242.110.* 回复 引用
博主,麻烦发一份啊,不胜感激,邮箱:kbl81716@
2009-03-02 15:07 | 迷离无间[未注册用户]
#14楼 58.17.231.* 回复 引用
感谢!
我邮箱是:cmy8653@
2009-03-02 22:28 | cmy
#15楼 210.77.87.* 回复 引用
麻烦发一份啊,不胜感激,最好可以发DCOM的配置的文档和OPC服务器,OPC服务器:你这个挺多items的我需要一个多点的items的服务器来测试一下。
datianyo@
2009-03-03 16:58 | 特尼[未注册用户]
#16楼 121.229.101.* 回复 引用
谢谢博主!资料很好!可能的话给我一份参考下,麻烦了!
comapple@
2009-03-04 09:59 | Zoo1234[未注册用户]
#17楼 60.19.219.* 回复 引用
你好我现在站在研究想看看一看,可以给我发一份吗
2009-03-05 10:49 | 庄子[未注册用户]
#18楼 59.46.
展开阅读全文