using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Client;
using Siemens.UAClientHelper;
namespace opcsharp
{
[Guid("b164ff91-e190-4881-aa5a-d92df9178233")]
public interface IOpcSharp
{
[DispId(1)]
int Connect(string url, bool security);
[DispId(2)]
int Disconnect();
[DispId(3)]
string ReadNode(string nodeid);
[DispId(4)]
int WriteNode(string nodeid, string value);
[DispId(5)]
String[] DiscoveryServers(string discovery);
}
[Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IOpcEvents
{
}
[Guid("02763ae4-c1e2-4b04-ae96-8dc65dbe18a0"),
ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IOpcEvents))]
public class COpcSharp : IOpcSharp
{
private static Session mySession;
private static bool started = false;
private static UAClientHelperAPI myClientHelperAPI = new UAClientHelperAPI();
private string discoveryUrl = "";
private bool securitybal =false;
public bool Connect()
{
try
{
if (started)
{
return true;
}
ApplicationDescriptionCollection servers = myClientHelperAPI.FindServers(discoveryUrl);
foreach (ApplicationDescription ad in servers)
{
foreach (string url in ad.DiscoveryUrls)
{
EndpointDescriptionCollection endpoints = myClientHelperAPI.GetEndpoints(url);
foreach (EndpointDescription endpoint in endpoints)
{
myClientHelperAPI.Connect(endpoint);
mySession = myClientHelperAPI.Session;
//myClientHelperAPI.KeepAliveNotification += new KeepAliveEventHandler(Notification_KeepAlive);
myClientHelperAPI.DisconnectedNotification += DisconnectedNotification;
ReportDebug("连接到终结点" + endpoint.EndpointUrl);
started = true;
return true;
}
}
}
}
catch (Exception e)
{
ReportError(e.ToString());
}
return false;
}
private void DisconnectedNotification(Session session, Exception e)
{
AutoReconnect();
}
public void AutoReconnect()
{
try
{
if (mySession != null && !mySession.Disposed)
{
myClientHelperAPI.Disconnect();
}
started = false;
myClientHelperAPI.Connect(discoveryUrl, securitybal);
started = true;
}
catch (Exception ex)
{
ReportError(ex.ToString());
}
}
private void ReportDebug(string MsgText, params object[] args)
{
ReportDebug(string.Format(MsgText, args));
}
private void ReportError(string MsgText, params object[] args)
{
ReportError(string.Format(MsgText, args));
}
private void ReportDebug(string MsgText)
{
ReportInfo(MsgText);
}
private void ReportInfo(string MsgText, params object[] args)
{
ReportInfo(string.Format(MsgText, args));
}
public void ReportInfo(string MsgText)
{
try
{
ReportInfoInternal(MsgText);
}
catch (Exception e)
{
}
}
public void ReportError(string MsgText)
{
try
{
ReportErrorInternal(MsgText);
}
catch (Exception e)
{
}
}
private void ReportInfoInternal(string MsgText)
{
try
{
}
catch (Exception e)
{
}
}
private void ReportErrorInternal(string MsgText)
{
try
{
}
catch (Exception e)
{
}
}
public int Disconnect()
{
try
{
if (!started)
{
return 1;
}
if (mySession != null && !mySession.Disposed)
{
myClientHelperAPI.DisconnectedNotification -= DisconnectedNotification;
myClientHelperAPI.Disconnect();
mySession = null;
}
started = false;
ReportDebug("断开连接到终结点");
return 0;
}
catch (Exception e)
{
}
return 1;
}
public int Connect(string url, bool security)
{
try
{
started = false;
discoveryUrl =url;
myClientHelperAPI.Connect(url, security);
myClientHelperAPI.DisconnectedNotification += DisconnectedNotification;
securitybal = security;
started = true;
return 0;
}
catch (Exception e)
{
}
return 1;
}
public String[] DiscoveryServers(string discovery)
{
List ret = new List();
try
{
ApplicationDescriptionCollection servers = myClientHelperAPI.FindServers(discovery);
foreach (ApplicationDescription ad in servers)
{
foreach (string url in ad.DiscoveryUrls)
{
EndpointDescriptionCollection endpoints = myClientHelperAPI.GetEndpoints(url);
foreach (EndpointDescription endpoint in endpoints)
{
ret.Add(endpoint.EndpointUrl);
}
}
}
}
catch (Exception ex)
{
ReportError(ex.ToString());
}
return ret.ToArray();
}
public string ReadNode(string nodeid)
{
try
{
if (started)
{
List values = new List();
List nodeIdStrings = new List();
nodeIdStrings.Add(nodeid);
nodeIdStrings = myClientHelperAPI.ReadValues(values);
if (nodeIdStrings.Any())
{
return nodeIdStrings.FirstOrDefault();
}
}
else
{
return "";
}
}
catch (Exception e)
{
}
return "";
}
public int WriteNode(string nodeid, string value)
{
try
{
if (started)
{
List values = new List();
List nodeIdStrings = new List();
values.Add(value);
nodeIdStrings.Add(nodeid);
myClientHelperAPI.WriteValues(values, nodeIdStrings);
}
else
{
return 1;
}
}
catch (Exception e)
{
}
return 1;
}
}
}
打开AssemblyInfo.cs。在里面加入[assembly:AssemblyKeyFile(“MyCom.snk”)],将ComVisible设置为true,打开项目配置,勾选 项目属性-生成-为COM互操作注册,项目属性-签名,为程序集签名"MyCom.snk"
注册com组件
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "E:\git\hmc\opcsharp\opcsharp\bin\x86\Debug\opcsharp.dll" /tlb /codebase
C:\Windows\System32>where GACUTIL
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\gacutil.exe
卸载方法
GACUTIL /u "opcsharp"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "E:\git\hmc\opcsharp\opcsharp\bin\x86\Debug\opcsharp.dll" /tlb /codebase
注册程序集方法
GACUTIL /i "E:\git\hmc\opcsharp\opcsharp\bin\x86\Debug\opcsharp.dll"
引用的程序集必须"MyCom.snk"签名才能加到缓存,解决0x80131534 的 HRESULT COR_E_TYPEINITIALIZATION。
GACUTIL /i "E:\git\hmc\opcsharp\opcsharp\bin\x86\Debug\Opc.Ua.Client.dll"
GACUTIL /i "E:\git\hmc\opcsharp\opcsharp\bin\x86\Debug\Opc.Ua.Core.dll"