首先注冊DLL
我這里把此DLL放到我自己的網站上了,供大家下載
https://blog.nwctwang.top/OPCDAAuto.dll
把此dll復制到C:\Windows\SysWOW64目錄下
以管理員身份運行CMD
cd C:\Windows\SysWOW64
regsvr32 OPCDAAuto.dll
然后就可以在VS中使用了
由於手頭沒有現成的OPC服務器和PLC設備,故采用KepServer模擬
安裝方法就不贅述了,安裝完打開是這樣
啟動完服務器,先到項目里引入剛才的DLL然后再擼代碼,直接上成品
其中的treeView控件、textBox控件需要你自己定義。
其余要注意的點已用注釋寫出
using OPCAutomation; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace XSDLOPCClinet { public partial class Form1 : Form { OPCServer ObjOPCServer; OPCGroups ObjOPCGroups; OPCGroup ObjOPCGroup; string OPCServerName; public Form1() { try { InitializeComponent(); OPCServerName = "Kepware.KEPServerEX.V5"; ObjOPCServer = new OPCServer(); ObjOPCServer.Connect(OPCServerName, "127.0.0.1");// 啟動一個Connect會頂掉其他線程的Connect,注意 object serverList = ObjOPCServer.GetOPCServers(); OPCBrowser opcBrowser = ObjOPCServer.CreateBrowser(); TreeNode Root = treeView1.Nodes.Add(ObjOPCServer.ServerName); Root.Tag = ObjOPCServer; opcBrowser.MoveToRoot(); ShowInTreeView(opcBrowser, Root); ObjOPCGroups = ObjOPCServer.OPCGroups; ObjOPCGroup = ObjOPCGroups.Add("Data Type Examples.16 Bit Device.R Registers");// 組名對應的是左邊樹狀第一大項里的小項 ObjOPCGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(ObjOPCGroup_DataChange); // 第一個參數是設備Tag名(加上group),第二個參數是item ID,是自己定義的,用於ObjOPCGroup_DataChange獲取相應ID的item數據 ObjOPCGroup.OPCItems.AddItem("Data Type Examples.16 Bit Device.R Registers.Double1", 1);// Item對應的是組名里的Tag,一定要寫全稱,否則報錯 ObjOPCGroup.OPCItems.AddItem("Data Type Examples.16 Bit Device.R Registers.Float1", 2); // ObjOPCGroup.UpdateRate = 100; // 刷新速率 ObjOPCGroup.IsActive = true; ObjOPCGroup.IsSubscribed = true; } catch (Exception e) { MessageBox.Show(e.ToString()); } } // 當數據發生變化時,采取的動作 private void ObjOPCGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps) { for (int i = 1; i <= NumItems; i++) { if ((Convert.ToInt32(ClientHandles.GetValue(i)) == 1))// ID為1的設備數據 { textBox1.Text = ItemValues.GetValue(i).ToString(); } if ((Convert.ToInt32(ClientHandles.GetValue(i)) == 2))// ID為2的設備數據 { textBox2.Text = ItemValues.GetValue(i).ToString(); } } } // 樹狀展示設備節點 private void ShowInTreeView(OPCBrowser brower, TreeNode node) { TreeNode childNode = null; brower.ShowBranches(); int BranchCount = brower.Count; List<string> lst = null; if (brower.Count > 0) //回溯的添加branch { lst = new List<string>(); foreach (string t in brower) lst.Add(t); foreach (string branch in lst) { childNode = new TreeNode(branch); childNode.Tag = brower.GetItemID(branch); node.Nodes.Add(childNode); brower.MoveDown(branch); ShowInTreeView(brower, childNode); brower.MoveUp(); } } brower.ShowLeafs(); int LeafsCount = brower.Count; foreach (string leaf in brower) { childNode = new TreeNode(brower.GetItemID(leaf)); childNode.Tag = brower.GetItemID(leaf); node.Nodes.Add(childNode); } } // 退出時釋放資源 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { ObjOPCServer.Disconnect(); } } }