C#开发OPC DA客户端的服务器状态处理

C#开发OPC DA客户端,最简单的方法是使用OpcRcw.Comn.dll,OpcRcw.Da.dll封装的API进行。OPC基金会的网站上,也可以下载到这两个库的原始文件DataAccess.cs和Common.cs直接集成到工程中来。

如何使用C#开发OPC DA Client程序,网上有很多例子,包括各大自动化厂商和OPC服务器厂商都带有相关的示例,在此不在重复。本文仅仅讨论如何处理与OPC服务器的连接状态问题。

首先,我们来看看OPC服务器的服务层接口定义,如下图(来源《Data Access Custom Interface Standard Version 2.05A》P6)所示:

C#开发OPC DA客户端的服务器状态处理_第1张图片

这里有两个重要的接口:IOPCServer和IConnectionPointContainer。IOPCServer实现了对OPC的服务器管理,包括组的添加和维护、服务器状态的获取等。IConnectionPointContainer在不同的接口中都有出现,不同层的定义有区别,在OPC服务器这层,他实现了IOPCShutdown的事件订阅,其他层的使用可以查看OPC规范定义。

下面的代码段,对如何使用有简单的示例。

public class OpcDaClient : IOPCDataCallback, IOPCShutdown
    {
        Type OPCServerType;
        IOPCServer OPCServer = null;
        IConnectionPointContainer pICPCShutdown = null;
        IConnectionPoint pICPShutdown = null;

        ///其他定义和方法处理

        [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        [MTAThread]
        static extern object CoCreateInstance(
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
            int pUnkOuter,
            int dwClsContext,
            [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid
        );
        [MTAThread]
        private void ConnectOpcServer()
        {
            try
            {
                 Guid DaServerGuid = Guid.Parse("...DaServerGuid");

                if (DaServerGuid == Guid.Empty)
                    OPCServerType = Type.GetTypeFromProgID("...DaServer ProgID", "...Host or Ip", true);
                else
                    OPCServerType = Type.GetTypeFromCLSID(DaServerGuid, "...Host or Ip", true);
                
                object obj = System.Activator.CreateInstance(OPCServerType);
                OPCServer = (IOPCServer)obj;
                pICPCShutdown = (IConnectionPointContainer)obj;
                if (pICPCShutdown != null )
                {
                    Guid iid = typeof(IOPCShutdown).GUID;
                    pICPCShutdown.FindConnectionPoint(ref iid, out pICPShutdown);
                    if (pICPShutdown != null)
                        pICPShutdown.Advise(this, out int dwCookie);
                }
            }
            catch (Exception ex)
            {
                OPCServer = null;
                //"ConnectOpcServer: " + ex.Message;
            }
        }
        [DllImport("oleaut32.dll")]
        public static extern void VariantClear(IntPtr pVariant);

        //dwTransid自动更新时为0,使用IOPCAsyncIO2::Refresh2手工刷新时,有参数dwTransactionID指定
        public void OnDataChange(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps, int[] pErrors)
        {
            //订阅数据处理
        }
        public void OnReadComplete(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps, int[] pErrors)
        {
        }

        public void OnWriteComplete(int dwTransid, int hGroup, int hrMastererr, int dwCount, int[] pClienthandles, int[] pErrors)
        {
        }

        public void OnCancelComplete(int dwTransid, int hGroup)
        {
        }

        /// 
        /// Opc服务器状态
        /// 
        /// String[] OPC服务器信息
        private string[] GetOpcServerStatus()
        {
            try
            {
                if (OPCServer != null)
                {
                    IntPtr ppServerStatus = IntPtr.Zero;
                    OPCServer.GetStatus(out ppServerStatus);

                    OPCSERVERSTATUS result = (OPCSERVERSTATUS)Marshal.PtrToStructure(ppServerStatus, typeof(OPCSERVERSTATUS));
                    Marshal.DestroyStructure(ppServerStatus, typeof(OpcRcw.Da.OPCSERVERSTATUS));
                    Marshal.FreeCoTaskMem(ppServerStatus);

                    List info = new List
                {
                    "ProgID:         " + appConfigDaClient.DaServer,
                    "StartTime:      " + ToDateTime(result.ftStartTime).ToString("yyyy-MM-dd HH:mm:ss"),
                    "CurrentTime:    " + ToDateTime(result.ftCurrentTime).ToString("yyyy-MM-dd HH:mm:ss"),
                    "LastUpdateTime: " + ToDateTime(result.ftLastUpdateTime).ToString("yyyy-MM-dd HH:mm:ss"),
                    "ServerState:    " + result.dwServerState.ToString(),
                    "MajorVersion:   " + result.wMajorVersion.ToString(),
                    "MinorVersion:   " + result.wMinorVersion.ToString(),
                    "BuildNumber:    " + result.wBuildNumber.ToString(),
                    "VendorInfo:     " + result.szVendorInfo
                };
                    return info.ToArray();
                }
            }catch(Exception ex)
            {
                //有异常,断开处理
            }
            return null;
        }

        
        public void ShutdownRequest([MarshalAs(UnmanagedType.LPWStr)] string szReason)
        {
            //服务器断开消息处理
            //注意,仅服务器优雅停止时才能收到断开消息
        }
    }

OpcRcw.Comn.dll 对应的Common.cs如下:

/* ========================================================================
 * Copyright (c) 2005-2017 The OPC Foundation, Inc. All rights reserved.
 *
 * OPC Foundation MIT License 1.00
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * The complete license agreement can be found here:
 * http://opcfoundation.org/License/MIT/1.00/
 * ======================================================================*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace OpcRcw.Comn
{    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]    
    public struct CONNECTDATA 
    {
        [MarshalAs(UnmanagedType.IUnknown)]
        object pUnk;
        [MarshalAs(UnmanagedType.I4)]
        int dwCookie;
    }

    [ComImport]
    [GuidAttribute("B196B287-BAB4-101A-B69C-00AA00341D07")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumConnections
    {
        void RemoteNext(
            [MarshalAs(UnmanagedType.I4)]
            int cConnections,
            [Out]
            IntPtr rgcd,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pcFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int cConnections);

        void Reset();

        void Clone(
            [Out]
            out IEnumConnections ppEnum);
    }

    [ComImport]
    [GuidAttribute("B196B286-BAB4-101A-B69C-00AA00341D07")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IConnectionPoint
    {
        void GetConnectionInterface(
            [Out]
            out Guid pIID);

        void GetConnectionPointContainer(
            [Out]
            out IConnectionPointContainer ppCPC);

        void Advise(
            [MarshalAs(UnmanagedType.IUnknown)]
            object pUnkSink,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pdwCookie);

        void Unadvise(
            [MarshalAs(UnmanagedType.I4)]
            int dwCookie);

        void EnumConnections(
            [Out]
            out IEnumConnections ppEnum);
    }

    [ComImport]
    [GuidAttribute("B196B285-BAB4-101A-B69C-00AA00341D07")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumConnectionPoints 
    {
        void RemoteNext(
            [MarshalAs(UnmanagedType.I4)]
            int cConnections,
            [Out]
            IntPtr ppCP,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pcFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int cConnections);

        void Reset();

        void Clone(
            [Out]
            out IEnumConnectionPoints ppEnum);
    }

    [ComImport]
    [GuidAttribute("B196B284-BAB4-101A-B69C-00AA00341D07")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IConnectionPointContainer
    {
        void EnumConnectionPoints(
            [Out]
            out IEnumConnectionPoints ppEnum);

        void FindConnectionPoint(
            ref Guid riid,
            [Out]
            out IConnectionPoint ppCP);
    }

    [ComImport]
    [GuidAttribute("F31DFDE1-07B6-11d2-B2D8-0060083BA1FB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCShutdown
    {
        void ShutdownRequest(
            [MarshalAs(UnmanagedType.LPWStr)]
            string szReason);
    }

    [ComImport]
    [GuidAttribute("F31DFDE2-07B6-11d2-B2D8-0060083BA1FB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCCommon 
    {
        void SetLocaleID(
            [MarshalAs(UnmanagedType.I4)]
            int dwLcid);

        void GetLocaleID(
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pdwLcid);

        void QueryAvailableLocaleIDs( 
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pdwCount,    
            [Out]
            out IntPtr pdwLcid);

        void GetErrorString( 
            [MarshalAs(UnmanagedType.I4)]
            int dwError,
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out String ppString);

        void SetClientName(
            [MarshalAs(UnmanagedType.LPWStr)] 
            String szName);
    }
    
    [ComImport]
    [GuidAttribute("13486D50-4821-11D2-A494-3CB306C10000")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCServerList 
    {
        void EnumClassesOfCategories(
            [MarshalAs(UnmanagedType.I4)]
            int cImplemented,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]
            Guid[] rgcatidImpl,
            [MarshalAs(UnmanagedType.I4)]
            int cRequired,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=2)]
            Guid[] rgcatidReq,
            [Out][MarshalAs(UnmanagedType.IUnknown)]
            out object ppenumClsid);

        void GetClassDetails(
            ref Guid clsid, 
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out string ppszProgID,
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out string ppszUserType);

        void CLSIDFromProgID(
            [MarshalAs(UnmanagedType.LPWStr)]
            string szProgId,
            [Out]
            out Guid clsid);
    }

    [ComImport]
    [GuidAttribute("55C382C8-21C7-4e88-96C1-BECFB1E3F483")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCEnumGUID 
    {
        void Next(
            [MarshalAs(UnmanagedType.I4)]
            int celt,
            [Out]
            IntPtr rgelt,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pceltFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int celt);

        void Reset();

        void Clone(
            [Out]
            out IOPCEnumGUID ppenum);
    }

    [ComImport]
    [GuidAttribute("0002E000-0000-0000-C000-000000000046")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumGUID 
    {
        void Next(
            [MarshalAs(UnmanagedType.I4)]
            int celt,
            [Out]
            IntPtr rgelt,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pceltFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int celt);

        void Reset();

        void Clone(
            [Out]
            out IEnumGUID ppenum);
    }

    [ComImport]
    [GuidAttribute("00000100-0000-0000-C000-000000000046")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumUnknown 
    {
        void RemoteNext(
            [MarshalAs(UnmanagedType.I4)]
            int celt,
            [Out]
            IntPtr rgelt,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pceltFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int celt);

        void Reset();

        void Clone(
            [Out]
            out IEnumUnknown ppenum);
    }
    
    [ComImport]
    [GuidAttribute("00000101-0000-0000-C000-000000000046")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumString 
    {
        [PreserveSig]
        int RemoteNext(
            [MarshalAs(UnmanagedType.I4)]
            int celt,
            IntPtr rgelt,
            [Out][MarshalAs(UnmanagedType.I4)]
            out int pceltFetched);

        void Skip(
            [MarshalAs(UnmanagedType.I4)]
            int celt);

        void Reset();

        void Clone(
            [Out]
            out IEnumString ppenum);
    }

    [ComImport]
    [GuidAttribute("9DD0B56C-AD9E-43ee-8305-487F3188BF7A")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCServerList2
    {
        void EnumClassesOfCategories(
            [MarshalAs(UnmanagedType.I4)]
            int cImplemented,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]
            Guid[] rgcatidImpl,
            [MarshalAs(UnmanagedType.I4)]
            int cRequired,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]
            Guid[] rgcatidReq,
            [Out]
            out IOPCEnumGUID ppenumClsid);

        void GetClassDetails(
            ref Guid clsid, 
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out string ppszProgID,
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out string ppszUserType,
            [Out][MarshalAs(UnmanagedType.LPWStr)]
            out string ppszVerIndProgID);

        void CLSIDFromProgID(
            [MarshalAs(UnmanagedType.LPWStr)]
            string szProgId,
            [Out]
            out Guid clsid);
    }
}

OpcRcw.Da.dll 对应的DataAccess.cs如下:

/* ========================================================================
 * Copyright (c) 2005-2017 The OPC Foundation, Inc. All rights reserved.
 *
 * OPC Foundation MIT License 1.00
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * The complete license agreement can be found here:
 * http://opcfoundation.org/License/MIT/1.00/
 * ======================================================================*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace OpcRcw.Da
{
    [ComImport]
    [GuidAttribute("63D5F430-CFE4-11d1-B2C8-0060083BA1FB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface CATID_OPCDAServer10 {}
    
    [ComImport]
    [GuidAttribute("63D5F432-CFE4-11d1-B2C8-0060083BA1FB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface CATID_OPCDAServer20 {}
    
    [ComImport]
    [GuidAttribute("CC603642-66D7-48f1-B69A-B625E73652D7")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface CATID_OPCDAServer30 {}
    
    [ComImport]
    [GuidAttribute("3098EDA4-A006-48b2-A27F-247453959408")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface CATID_XMLDAServer10 {}

    public enum OPCDATASOURCE 
    { 
        OPC_DS_CACHE = 1, 
        OPC_DS_DEVICE 
    } 
    
    public enum OPCBROWSETYPE 
    { 
        OPC_BRANCH = 1, 
        OPC_LEAF, 
        OPC_FLAT
    } 

    public enum OPCNAMESPACETYPE 
    { 
        OPC_NS_HIERARCHIAL = 1, 
        OPC_NS_FLAT
    }

    public enum OPCBROWSEDIRECTION 
    { 
        OPC_BROWSE_UP = 1, 
        OPC_BROWSE_DOWN, 
        OPC_BROWSE_TO
    } 

    public enum OPCEUTYPE 
    {
        OPC_NOENUM = 0, 
        OPC_ANALOG, 
        OPC_ENUMERATED 
    } 

    public enum OPCSERVERSTATE 
    { 
        OPC_STATUS_RUNNING = 1, 
        OPC_STATUS_FAILED, 
        OPC_STATUS_NOCONFIG, 
        OPC_STATUS_SUSPENDED, 
        OPC_STATUS_TEST,
        OPC_STATUS_COMM_FAULT
    } 

    public enum OPCENUMSCOPE 
    { 
        OPC_ENUM_PRIVATE_CONNECTIONS = 1, 
        OPC_ENUM_PUBLIC_CONNECTIONS, 
        OPC_ENUM_ALL_CONNECTIONS, 
        OPC_ENUM_PRIVATE, 
        OPC_ENUM_PUBLIC, 
        OPC_ENUM_ALL 
    } 
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCGROUPHEADER 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int dwSize;
        [MarshalAs(UnmanagedType.I4)]
        public int dwItemCount;
        [MarshalAs(UnmanagedType.I4)]
        public int hClientGroup;
        [MarshalAs(UnmanagedType.I4)]
        public int dwTransactionID;
        [MarshalAs(UnmanagedType.I4)]
        public int hrStatus;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMHEADER1 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        [MarshalAs(UnmanagedType.I4)]
        public int dwValueOffset;
        [MarshalAs(UnmanagedType.I2)]
        public short wQuality;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStampItem;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMHEADER2 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        [MarshalAs(UnmanagedType.I4)]
        public int dwValueOffset;
        [MarshalAs(UnmanagedType.I2)]
        public short wQuality;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCGROUPHEADERWRITE 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int dwItemCount;
        [MarshalAs(UnmanagedType.I4)]
        public int hClientGroup;
        [MarshalAs(UnmanagedType.I4)]
        public int dwTransactionID;
        [MarshalAs(UnmanagedType.I4)]
        public int hrStatus;
    } 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMHEADERWRITE 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        [MarshalAs(UnmanagedType.I4)]
        public int dwError;
    } 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMSTATE
    {
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStamp;
        [MarshalAs(UnmanagedType.I2)]
        public short wQuality;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
        [MarshalAs(UnmanagedType.Struct)]
        public object vDataValue;
    } 

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCSERVERSTATUS 
    {
        public System.Runtime.InteropServices.ComTypes.FILETIME ftStartTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftCurrentTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastUpdateTime;
        public OPCSERVERSTATE dwServerState;
        [MarshalAs(UnmanagedType.I4)]
        public int dwGroupCount; 
        [MarshalAs(UnmanagedType.I4)]
        public int dwBandWidth;
        [MarshalAs(UnmanagedType.I2)]
        public short wMajorVersion;
        [MarshalAs(UnmanagedType.I2)]
        public short wMinorVersion;
        [MarshalAs(UnmanagedType.I2)]
        public short wBuildNumber;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szVendorInfo;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMDEF 
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szAccessPath;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szItemID;
        [MarshalAs(UnmanagedType.I4)]
        public int bActive;
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        [MarshalAs(UnmanagedType.I4)]
        public int dwBlobSize;
        public IntPtr pBlob;
        [MarshalAs(UnmanagedType.I2)]
        public short vtRequestedDataType;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
    };
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMATTRIBUTES
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szAccessPath;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szItemID;
        [MarshalAs(UnmanagedType.I4)]
        public int bActive;
        [MarshalAs(UnmanagedType.I4)]
        public int hClient;
        [MarshalAs(UnmanagedType.I4)]
        public int hServer;
        [MarshalAs(UnmanagedType.I4)]
        public int dwAccessRights;
        [MarshalAs(UnmanagedType.I4)]
        public int dwBlobSize;
        public IntPtr pBlob;
        [MarshalAs(UnmanagedType.I2)]
        public short vtRequestedDataType;
        [MarshalAs(UnmanagedType.I2)]
        public short vtCanonicalDataType;
        public OPCEUTYPE  dwEUType;
        [MarshalAs(UnmanagedType.Struct)]
        public object vEUInfo;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMRESULT 
    {
        [MarshalAs(UnmanagedType.I4)]
        public int hServer;
        [MarshalAs(UnmanagedType.I2)]
        public short vtCanonicalDataType;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
        [MarshalAs(UnmanagedType.I4)]
        public int dwAccessRights;
        [MarshalAs(UnmanagedType.I4)]
        public int dwBlobSize;
        public IntPtr pBlob;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMPROPERTY
    {
        [MarshalAs(UnmanagedType.I2)]
        public short vtDataType;
        [MarshalAs(UnmanagedType.I2)]
        public short wReserved;
        [MarshalAs(UnmanagedType.I4)]
        public int    dwPropertyID;  
        [MarshalAs(UnmanagedType.LPWStr)] 
        public string szItemID;
        [MarshalAs(UnmanagedType.LPWStr)] 
        public string szDescription;
        [MarshalAs(UnmanagedType.Struct)] 
        public object vValue;
        [MarshalAs(UnmanagedType.I4)] 
        public int    hrErrorID;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwReserved;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMPROPERTIES 
    {
        [MarshalAs(UnmanagedType.I4)] 
        public int hrErrorID;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwNumProperties;
        public IntPtr pItemProperties;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwReserved;
    } 
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCBROWSEELEMENT
    {
        [MarshalAs(UnmanagedType.LPWStr)] 
        public string szName;
        [MarshalAs(UnmanagedType.LPWStr)] 
        public string szItemID;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwFlagValue;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwReserved; 
        public OPCITEMPROPERTIES ItemProperties;
    }
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct OPCITEMVQT
    {
        [MarshalAs(UnmanagedType.Struct)] 
        public object vDataValue;
        [MarshalAs(UnmanagedType.I4)] 
        public int bQualitySpecified;
        [MarshalAs(UnmanagedType.I2)] 
        public short wQuality;
        [MarshalAs(UnmanagedType.I2)] 
        public short wReserved;
        [MarshalAs(UnmanagedType.I4)] 
        public int bTimeStampSpecified;
        [MarshalAs(UnmanagedType.I4)] 
        public int dwReserved;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStamp;
    } 

    public enum OPCBROWSEFILTER 
    {
        OPC_BROWSE_FILTER_ALL = 1,
        OPC_BROWSE_FILTER_BRANCHES,
        OPC_BROWSE_FILTER_ITEMS,
    } 

    [ComImport]
    [GuidAttribute("39c13a4d-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCServer
    {
        void AddGroup(
            [MarshalAs(UnmanagedType.LPWStr)] 
            string szName,
            [MarshalAs(UnmanagedType.I4)] 
            int bActive,
            [MarshalAs(UnmanagedType.I4)] 
            int dwRequestedUpdateRate,
            [MarshalAs(UnmanagedType.I4)] 
            int hClientGroup,
            IntPtr pTimeBias,
            IntPtr pPercentDeadband,
            [MarshalAs(UnmanagedType.I4)] 
            int dwLCID,
            [Out][MarshalAs(UnmanagedType.I4)] 
            out int phServerGroup,
            [Out][MarshalAs(UnmanagedType.I4)] 
            out int pRevisedUpdateRate,
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=9)] 
            out object ppUnk);

        void GetErrorString( 
            [MarshalAs(UnmanagedType.I4)] 
            int dwError,
            [MarshalAs(UnmanagedType.I4)] 
            int dwLocale,
            [Out][MarshalAs(UnmanagedType.LPWStr)] 
            out string ppString);

        void GetGroupByName(
            [MarshalAs(UnmanagedType.LPWStr)] 
            string szName,
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=1)] 
            out object ppUnk);

        void GetStatus( 
            [Out]
            out IntPtr ppServerStatus);

        void RemoveGroup(
            [MarshalAs(UnmanagedType.I4)] 
            int hServerGroup,
            [MarshalAs(UnmanagedType.I4)] 
            int bForce);

        void CreateGroupEnumerator(
            OPCENUMSCOPE dwScope, 
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=1)] 
            out object ppUnk);
    }

    [ComImport]
    [GuidAttribute("39c13a4e-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCServerPublicGroups
    {
        void GetPublicGroupByName(
            [MarshalAs(UnmanagedType.LPWStr)] 
            string szName, 
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=1)] 
            out object ppUnk);

        void RemovePublicGroup(
            [MarshalAs(UnmanagedType.I4)] 
            int hServerGroup,
            [MarshalAs(UnmanagedType.I4)] 
            int bForce);
    }

    [ComImport]
    [GuidAttribute("39c13a4f-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCBrowseServerAddressSpace
    {
        void QueryOrganization(
            [Out] 
            out OPCNAMESPACETYPE pNameSpaceType);

        void ChangeBrowsePosition(
            OPCBROWSEDIRECTION dwBrowseDirection, 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szString);

        void BrowseOPCItemIDs(
            OPCBROWSETYPE dwBrowseFilterType, 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string  szFilterCriteria, 
            [MarshalAs(UnmanagedType.I2)]  
            short vtDataTypeFilter, 
            [MarshalAs(UnmanagedType.I4)]  
            int dwAccessRightsFilter,
            [Out] 
            out OpcRcw.Comn.IEnumString ppIEnumString);        

        void GetItemID(
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemDataID,
            [Out][MarshalAs(UnmanagedType.LPWStr)]  
            out string szItemID);

        void BrowseAccessPaths(
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemID,
            [Out] 
            out OpcRcw.Comn.IEnumString pIEnumString);
    }

    [ComImport]
    [GuidAttribute("39c13a50-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCGroupStateMgt
    {
        void GetState(
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pUpdateRate, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pActive,
            [Out][MarshalAs(UnmanagedType.LPWStr)]  
            out string ppName, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pTimeBias, 
            [Out][MarshalAs(UnmanagedType.R4)]  
            out float pPercentDeadband,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pLCID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int phClientGroup,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int phServerGroup);

        void SetState( 
            IntPtr pRequestedUpdateRate,  
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pRevisedUpdateRate, 
            IntPtr pActive, 
            IntPtr pTimeBias,
            IntPtr pPercentDeadband,
            IntPtr pLCID,
            IntPtr phClientGroup);

        void SetName( 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szName);

        void CloneGroup(
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szName, 
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=1)] 
            out object ppUnk);
    }

    [ComImport]
    [GuidAttribute("39c13a51-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCPublicGroupStateMgt
    {
        void GetState(  
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pPublic);

        void MoveToPublic();
    }

    [ComImport]
    [GuidAttribute("39c13a52-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCSyncIO
    {
        void Read(
            OPCDATASOURCE  dwSource,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=1)]  
            int[] phServer, 
            [Out] 
            out IntPtr ppItemValues,
            [Out] 
            out IntPtr ppErrors);

        void Write(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=0)]  
            object[] pItemValues, 
            [Out] 
            out IntPtr ppErrors);
    }

    [ComImport]
    [GuidAttribute("39c13a53-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCAsyncIO
    {
        void Read(
            [MarshalAs(UnmanagedType.I4)]  
            int dwConnection,
            OPCDATASOURCE dwSource,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=2)]  
            int[] phServer,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pTransactionID,
            [Out] 
            out IntPtr ppErrors);

        void Write(
            [MarshalAs(UnmanagedType.I4)]  
            int dwConnection,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=1)]  
            int[] phServer, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=1)]  
            object[] pItemValues, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pTransactionID,
            [Out] 
            out IntPtr ppErrors);

        void Refresh(
            [MarshalAs(UnmanagedType.I4)]  
            int dwConnection,
            OPCDATASOURCE dwSource, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pTransactionID);

        void Cancel(
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID);
    }

    [ComImport]
    [GuidAttribute("39c13a54-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCItemMgt
    {
        void AddItems( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]  
            OPCITEMDEF[] pItemArray,
            [Out] 
            out IntPtr ppAddResults,
            [Out] 
            out IntPtr ppErrors);

        void ValidateItems( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]  
            OPCITEMDEF[] pItemArray,
            [MarshalAs(UnmanagedType.I4)]  
            int bBlobUpdate,
            [Out] 
            out IntPtr ppValidationResults,
            [Out] 
            out IntPtr ppErrors);

        void RemoveItems( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [Out] 
            out IntPtr ppErrors);

        void SetActiveState(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.I4)]  
            int  bActive, 
            [Out] 
            out IntPtr ppErrors);

        void SetClientHandles(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phClient,
            [Out] 
            out IntPtr ppErrors);

        void SetDatatypes(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I2, SizeParamIndex=0)]  
            short[] pRequestedDatatypes,
            [Out] 
            out IntPtr ppErrors);

        void CreateEnumerator(
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=0)] 
            out object ppUnk);
    }

    [ComImport]
    [GuidAttribute("39c13a55-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IEnumOPCItemAttributes
    {
        void Next( 
            [MarshalAs(UnmanagedType.I4)]  
            int celt,
            [Out] 
            out IntPtr ppItemArray,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pceltFetched);

        void Skip( 
            [MarshalAs(UnmanagedType.I4)]  
            int celt);

        void Reset();

        void Clone( 
            [Out] 
            out IEnumOPCItemAttributes ppEnumItemAttributes);
    }

    [ComImport]
    [GuidAttribute("39c13a70-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCDataCallback
    {
        void OnDataChange(
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransid, 
            [MarshalAs(UnmanagedType.I4)]  
            int hGroup, 
            [MarshalAs(UnmanagedType.I4)]  
            int hrMasterquality,
            [MarshalAs(UnmanagedType.I4)]  
            int hrMastererror,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=4)]  
            int[] phClientItems, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=4)]  
            object[] pvValues, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I2, SizeParamIndex=4)]  
            short[] pwQualities,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=4)]  
            System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=4)]  
            int[] pErrors);

        void OnReadComplete(
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransid, 
            [MarshalAs(UnmanagedType.I4)]  
            int hGroup, 
            [MarshalAs(UnmanagedType.I4)]  
            int hrMasterquality,
            [MarshalAs(UnmanagedType.I4)]  
            int hrMastererror,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=4)]  
            int[] phClientItems, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=4)]  
            object[] pvValues, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I2, SizeParamIndex=4)]  
            short[] pwQualities,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=4)]  
            System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=4)]  
            int[] pErrors);

        void OnWriteComplete(
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransid, 
            [MarshalAs(UnmanagedType.I4)]  
            int hGroup, 
            [MarshalAs(UnmanagedType.I4)]  
            int hrMastererr, 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=3)]  
            int[] pClienthandles, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=3)]  
            int[] pErrors);

        void OnCancelComplete(
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransid, 
            [MarshalAs(UnmanagedType.I4)]  
            int hGroup);
    }

    [ComImport]
    [GuidAttribute("39c13a71-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCAsyncIO2
    {
        void Read(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void Write(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=0)]  
            object[] pItemValues, 
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void Refresh2(
            OPCDATASOURCE dwSource,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID);

        void Cancel2(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCancelID);

        void SetEnable(
            [MarshalAs(UnmanagedType.I4)]  
            int bEnable);

        void GetEnable(
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pbEnable);
    }

    [ComImport]
    [GuidAttribute("39c13a72-011e-11d0-9675-0020afd8adb3")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCItemProperties
    {
        void QueryAvailableProperties( 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCount,
            [Out] 
            out IntPtr ppPropertyIDs,
            [Out] 
            out IntPtr ppDescriptions,
            [Out] 
            out IntPtr ppvtDataTypes);

        void GetItemProperties( 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemID,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=1)]  
            int[] pdwPropertyIDs,
            [Out] 
            out IntPtr ppvData,
            [Out] 
            out IntPtr ppErrors);

        void LookupItemIDs( 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemID,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=1)]  
            int[] pdwPropertyIDs,
            [Out] 
            out IntPtr ppszNewItemIDs,
            [Out] 
            out IntPtr ppErrors);
    }

    [ComImport]
    [GuidAttribute("5946DA93-8B39-4ec8-AB3D-AA73DF5BC86F")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCItemDeadbandMgt
    {
        void SetItemDeadband( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.R4, SizeParamIndex=0)]  
            float[] pPercentDeadband,
            [Out] 
            out IntPtr ppErrors);

        void GetItemDeadband( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [Out] 
            out IntPtr ppPercentDeadband,
            [Out] 
            out IntPtr ppErrors);

        void ClearItemDeadband(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [Out] 
            out IntPtr ppErrors);
    }

    [ComImport]
    [GuidAttribute("3E22D313-F08B-41a5-86C8-95E95CB49FFC")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCItemSamplingMgt
    {
        void SetItemSamplingRate(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] pdwRequestedSamplingRate,
            [Out] 
            out IntPtr ppdwRevisedSamplingRate,
            [Out] 
            out IntPtr ppErrors);

        void GetItemSamplingRate(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [Out] 
            out IntPtr ppdwSamplingRate,
            [Out] 
            out IntPtr ppErrors);

        void ClearItemSamplingRate(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [Out] 
            out IntPtr ppErrors);

        void SetItemBufferEnable(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] pbEnable,
            [Out] 
            out IntPtr ppErrors);

        void GetItemBufferEnable(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer, 
            [Out] 
            out IntPtr ppbEnable,
            [Out] 
            out IntPtr ppErrors);
    }
    
    [ComImport]
    [GuidAttribute("39227004-A18F-4b57-8B0A-5235670F4468")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCBrowse
    {
        void GetProperties( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwItemCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=0)]  
            string[] pszItemIDs,
            [MarshalAs(UnmanagedType.I4)]  
            int bReturnPropertyValues,
            [MarshalAs(UnmanagedType.I4)]  
            int dwPropertyCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=3)]  
            int[] dwPropertyIDs,
            [Out] 
            out IntPtr ppItemProperties);

        void Browse(
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szItemID,
            ref IntPtr pszContinuationPoint,
            [MarshalAs(UnmanagedType.I4)]  
            int dwMaxElementsReturned,
            OPCBROWSEFILTER dwBrowseFilter,
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szElementNameFilter,
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szVendorFilter,
            [MarshalAs(UnmanagedType.I4)]  
            int bReturnAllProperties,
            [MarshalAs(UnmanagedType.I4)]  
            int bReturnPropertyValues,
            [MarshalAs(UnmanagedType.I4)]  
            int dwPropertyCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=8)]  
            int[] pdwPropertyIDs,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pbMoreElements,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCount,
            [Out] 
            out IntPtr ppBrowseElements);
    }

    [ComImport]
    [GuidAttribute("85C0B427-2893-4cbc-BD78-E5FC5146F08F")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCItemIO
    {
        void Read(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=0)]  
            string[] pszItemIDs, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] pdwMaxAge,
            [Out] 
            out IntPtr ppvValues,
            [Out] 
            out IntPtr ppwQualities,
            [Out] 
            out IntPtr ppftTimeStamps,
            [Out] 
            out IntPtr ppErrors);

        void WriteVQT(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=0)]  
            string[] pszItemIDs,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]  
            OPCITEMVQT[] pItemVQT,
            [Out] 
            out IntPtr ppErrors);
    }
    
    [ComImport]
    [GuidAttribute("730F5F0F-55B1-4c81-9E18-FF8A0904E1FA")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCSyncIO2 // : IOPCSyncIO
    {  
        void Read(
            OPCDATASOURCE  dwSource,
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=1)]  
            int[] phServer, 
            [Out] 
            out IntPtr ppItemValues,
            [Out] 
            out IntPtr ppErrors);

        void Write(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=0)]  
            object[] pItemValues, 
            [Out] 
            out IntPtr ppErrors);

        void ReadMaxAge(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] pdwMaxAge,
            [Out] 
            out IntPtr ppvValues,
            [Out] 
            out IntPtr ppwQualities,
            [Out] 
            out IntPtr ppftTimeStamps,
            [Out] 
            out IntPtr ppErrors);

        void WriteVQT(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]  
            OPCITEMVQT[] pItemVQT,
            [Out] 
            out IntPtr ppErrors);
    }

    [ComImport]
    [GuidAttribute("0967B97B-36EF-423e-B6F8-6BFF1E40D39D")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCAsyncIO3 // : IOPCAsyncIO2
    { 
        void Read(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void Write(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=0)]  
            object[] pItemValues, 
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void Refresh2(
            OPCDATASOURCE dwSource,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID);

        void Cancel2(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCancelID);

        void SetEnable(
            [MarshalAs(UnmanagedType.I4)]  
            int bEnable);

        void GetEnable(
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pbEnable);

        void ReadMaxAge(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] pdwMaxAge,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out] 
            [MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void WriteVQT(
            [MarshalAs(UnmanagedType.I4)]  
            int dwCount, 
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeParamIndex=0)]  
            int[] phServer,
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStruct, SizeParamIndex=0)]  
            OPCITEMVQT[] pItemVQT,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out] 
            [MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID,
            [Out] 
            out IntPtr ppErrors);

        void RefreshMaxAge(
            [MarshalAs(UnmanagedType.I4)]  
            int dwMaxAge,
            [MarshalAs(UnmanagedType.I4)]  
            int dwTransactionID,
            [Out] 
            [MarshalAs(UnmanagedType.I4)]  
            out int pdwCancelID);
    }

    [ComImport]
    [GuidAttribute("8E368666-D72E-4f78-87ED-647611C61C9F")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IOPCGroupStateMgt2 // : IOPCGroupStateMgt
    { 
        void GetState(
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pUpdateRate, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pActive,
            [Out][MarshalAs(UnmanagedType.LPWStr)]  
            out string ppName, 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pTimeBias, 
            [Out][MarshalAs(UnmanagedType.R4)]  
            out float pPercentDeadband,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pLCID,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int phClientGroup,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int phServerGroup);

        void SetState( 
            IntPtr pRequestedUpdateRate,  
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pRevisedUpdateRate, 
            IntPtr pActive, 
            IntPtr pTimeBias,
            IntPtr pPercentDeadband,
            IntPtr pLCID,
            IntPtr phClientGroup);

        void SetName( 
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szName);

        void CloneGroup(
            [MarshalAs(UnmanagedType.LPWStr)]  
            string szName, 
            ref Guid riid,
            [Out][MarshalAs(UnmanagedType.IUnknown, IidParameterIndex=1)] 
            out object ppUnk);

        void SetKeepAlive( 
            [MarshalAs(UnmanagedType.I4)]  
            int dwKeepAliveTime,
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwRevisedKeepAliveTime);

        void GetKeepAlive( 
            [Out][MarshalAs(UnmanagedType.I4)]  
            out int pdwKeepAliveTime);
    }

    public static class Constants
    {
        // category description strings.
        public const string OPC_CATEGORY_DESCRIPTION_DA10    = "OPC Data Access Servers Version 1.0";
        public const string OPC_CATEGORY_DESCRIPTION_DA20    = "OPC Data Access Servers Version 2.0";
        public const string OPC_CATEGORY_DESCRIPTION_DA30    = "OPC Data Access Servers Version 3.0";
        public const string OPC_CATEGORY_DESCRIPTION_XMLDA10 = "OPC XML Data Access Servers Version 1.0";

        // values for access rights mask.
        public const int OPC_READABLE           = 0x01;
        public const int OPC_WRITEABLE          = 0x02;    

        // values for browse element flags.
        public const int OPC_BROWSE_HASCHILDREN = 0x01;
        public const int OPC_BROWSE_ISITEM      = 0x02;

        // well known complex type description systems.   
        public const string OPC_TYPE_SYSTEM_OPCBINARY             = "OPCBinary";
        public const string OPC_TYPE_SYSTEM_XMLSCHEMA             = "XMLSchema";

        // complex data consitency window values.
        public const string OPC_CONSISTENCY_WINDOW_UNKNOWN        = "Unknown";
        public const string OPC_CONSISTENCY_WINDOW_NOT_CONSISTENT = "Not Consistent";

        // complex data write behavoir values.
        public const string OPC_WRITE_BEHAVIOR_BEST_EFFORT        = "Best Effort";
        public const string OPC_WRITE_BEHAVIOR_ALL_OR_NOTHING     = "All or Nothing";
    }

    public static class Qualities
    {
        // Values for fields in the quality word
        public const short OPC_QUALITY_MASK                     = 0xC0;
        public const short OPC_STATUS_MASK                      = 0xFC;
        public const short OPC_LIMIT_MASK                       = 0x03;

        // Values for QUALITY_MASK bit field
        public const short OPC_QUALITY_BAD                      = 0x00;
        public const short OPC_QUALITY_UNCERTAIN                = 0x40;
        public const short OPC_QUALITY_GOOD                     = 0xC0;

        // STATUS_MASK Values for Quality = BAD
        public const short OPC_QUALITY_CONFIG_ERROR                = 0x04;
        public const short OPC_QUALITY_NOT_CONNECTED               = 0x08;
        public const short OPC_QUALITY_DEVICE_FAILURE              = 0x0c;
        public const short OPC_QUALITY_SENSOR_FAILURE              = 0x10;
        public const short OPC_QUALITY_LAST_KNOWN                  = 0x14;
        public const short OPC_QUALITY_COMM_FAILURE                = 0x18;
        public const short OPC_QUALITY_OUT_OF_SERVICE              = 0x1C;
        public const short OPC_QUALITY_WAITING_FOR_INITIAL_DATA = 0x20;

        // STATUS_MASK Values for Quality = UNCERTAIN
        public const short OPC_QUALITY_LAST_USABLE              = 0x44;
        public const short OPC_QUALITY_SENSOR_CAL               = 0x50;
        public const short OPC_QUALITY_EGU_EXCEEDED             = 0x54;
        public const short OPC_QUALITY_SUB_NORMAL               = 0x58;

        // STATUS_MASK Values for Quality = GOOD
        public const short OPC_QUALITY_LOCAL_OVERRIDE           = 0xD8;

        // Values for Limit Bitfield 
        public const short OPC_LIMIT_OK                         = 0x00;
        public const short OPC_LIMIT_LOW                        = 0x01;
        public const short OPC_LIMIT_HIGH                       = 0x02;
        public const short OPC_LIMIT_CONST                      = 0x03;
    }

    //==========================================================================
    // Properties
    
    public static class Properties
    {
        // property ids.
        public const int OPC_PROPERTY_DATATYPE            = 1;
        public const int OPC_PROPERTY_VALUE               = 2;
        public const int OPC_PROPERTY_QUALITY             = 3;
        public const int OPC_PROPERTY_TIMESTAMP           = 4;
        public const int OPC_PROPERTY_ACCESS_RIGHTS       = 5;
        public const int OPC_PROPERTY_SCAN_RATE           = 6;
        public const int OPC_PROPERTY_EU_TYPE             = 7;
        public const int OPC_PROPERTY_EU_INFO             = 8;
        public const int OPC_PROPERTY_EU_UNITS            = 100;
        public const int OPC_PROPERTY_DESCRIPTION         = 101;
        public const int OPC_PROPERTY_HIGH_EU             = 102;
        public const int OPC_PROPERTY_LOW_EU              = 103;
        public const int OPC_PROPERTY_HIGH_IR             = 104;
        public const int OPC_PROPERTY_LOW_IR              = 105;
        public const int OPC_PROPERTY_CLOSE_LABEL         = 106;
        public const int OPC_PROPERTY_OPEN_LABEL          = 107;
        public const int OPC_PROPERTY_TIMEZONE            = 108;
        public const int OPC_PROPERTY_CONDITION_STATUS    = 300;
        public const int OPC_PROPERTY_ALARM_QUICK_HELP    = 301;
        public const int OPC_PROPERTY_ALARM_AREA_LIST     = 302;
        public const int OPC_PROPERTY_PRIMARY_ALARM_AREA  = 303;
        public const int OPC_PROPERTY_CONDITION_LOGIC     = 304;
        public const int OPC_PROPERTY_LIMIT_EXCEEDED      = 305;
        public const int OPC_PROPERTY_DEADBAND            = 306;
        public const int OPC_PROPERTY_HIHI_LIMIT          = 307;
        public const int OPC_PROPERTY_HI_LIMIT            = 308;
        public const int OPC_PROPERTY_LO_LIMIT            = 309;
        public const int OPC_PROPERTY_LOLO_LIMIT          = 310;
        public const int OPC_PROPERTY_CHANGE_RATE_LIMIT   = 311;
        public const int OPC_PROPERTY_DEVIATION_LIMIT     = 312;
        public const int OPC_PROPERTY_SOUND_FILE          = 313;

        // complex data properties.
        public const int OPC_PROPERTY_TYPE_SYSTEM_ID      = 600;
        public const int OPC_PROPERTY_DICTIONARY_ID       = 601;
        public const int OPC_PROPERTY_TYPE_ID             = 602;
        public const int OPC_PROPERTY_DICTIONARY          = 603;
        public const int OPC_PROPERTY_TYPE_DESCRIPTION    = 604;
        public const int OPC_PROPERTY_CONSISTENCY_WINDOW  = 605;
        public const int OPC_PROPERTY_WRITE_BEHAVIOR      = 606;
        public const int OPC_PROPERTY_UNCONVERTED_ITEM_ID = 607;
        public const int OPC_PROPERTY_UNFILTERED_ITEM_ID  = 608;
        public const int OPC_PROPERTY_DATA_FILTER_VALUE   = 609;

        // property descriptions.
        public const string OPC_PROPERTY_DESC_DATATYPE            = "Item Canonical Data Type";
        public const string OPC_PROPERTY_DESC_VALUE               = "Item Value";
        public const string OPC_PROPERTY_DESC_QUALITY             = "Item Quality";
        public const string OPC_PROPERTY_DESC_TIMESTAMP           = "Item Timestamp";
        public const string OPC_PROPERTY_DESC_ACCESS_RIGHTS       = "Item Access Rights";
        public const string OPC_PROPERTY_DESC_SCAN_RATE           = "Server Scan Rate";
        public const string OPC_PROPERTY_DESC_EU_TYPE             = "Item EU Type";
        public const string OPC_PROPERTY_DESC_EU_INFO             = "Item EU Info";
        public const string OPC_PROPERTY_DESC_EU_UNITS            = "EU Units";
        public const string OPC_PROPERTY_DESC_DESCRIPTION         = "Item Description";
        public const string OPC_PROPERTY_DESC_HIGH_EU             = "High EU";
        public const string OPC_PROPERTY_DESC_LOW_EU              = "Low EU";
        public const string OPC_PROPERTY_DESC_HIGH_IR             = "High Instrument Range";
        public const string OPC_PROPERTY_DESC_LOW_IR              = "Low Instrument Range";
        public const string OPC_PROPERTY_DESC_CLOSE_LABEL         = "Contact Close Label";
        public const string OPC_PROPERTY_DESC_OPEN_LABEL          = "Contact Open Label";
        public const string OPC_PROPERTY_DESC_TIMEZONE            = "Item Timezone";
        public const string OPC_PROPERTY_DESC_CONDITION_STATUS    = "Condition Status";
        public const string OPC_PROPERTY_DESC_ALARM_QUICK_HELP    = "Alarm Quick Help";
        public const string OPC_PROPERTY_DESC_ALARM_AREA_LIST     = "Alarm Area List";
        public const string OPC_PROPERTY_DESC_PRIMARY_ALARM_AREA  = "Primary Alarm Area";
        public const string OPC_PROPERTY_DESC_CONDITION_LOGIC     = "Condition Logic";
        public const string OPC_PROPERTY_DESC_LIMIT_EXCEEDED      = "Limit Exceeded";
        public const string OPC_PROPERTY_DESC_DEADBAND            = "Deadband";
        public const string OPC_PROPERTY_DESC_HIHI_LIMIT          = "HiHi Limit";
        public const string OPC_PROPERTY_DESC_HI_LIMIT            = "Hi Limit";
        public const string OPC_PROPERTY_DESC_LO_LIMIT            = "Lo Limit";
        public const string OPC_PROPERTY_DESC_LOLO_LIMIT          = "LoLo Limit";
        public const string OPC_PROPERTY_DESC_CHANGE_RATE_LIMIT   = "Rate of Change Limit";
        public const string OPC_PROPERTY_DESC_DEVIATION_LIMIT     = "Deviation Limit";
        public const string OPC_PROPERTY_DESC_SOUND_FILE          = "Sound File";

        // complex data properties.
        public const string OPC_PROPERTY_DESC_TYPE_SYSTEM_ID      = "Type System ID";
        public const string OPC_PROPERTY_DESC_DICTIONARY_ID       = "Dictionary ID";
        public const string OPC_PROPERTY_DESC_TYPE_ID             = "Type ID";
        public const string OPC_PROPERTY_DESC_DICTIONARY          = "Dictionary";
        public const string OPC_PROPERTY_DESC_TYPE_DESCRIPTION    = "Type Description";
        public const string OPC_PROPERTY_DESC_CONSISTENCY_WINDOW  = "Consistency Window";
        public const string OPC_PROPERTY_DESC_WRITE_BEHAVIOR      = "Write Behavior";
        public const string OPC_PROPERTY_DESC_UNCONVERTED_ITEM_ID = "Unconverted Item ID";
        public const string OPC_PROPERTY_DESC_UNFILTERED_ITEM_ID  = "Unfiltered Item ID";
        public const string OPC_PROPERTY_DESC_DATA_FILTER_VALUE   = "Data Filter Value";
    }
}

你可能感兴趣的:(IoT,编程,c#,OPC,DA,IOPCShutdown)