同一计算机上的OPCClient与多个网络OPCServer通讯的解决办法(附带脚本)

上周帮一个朋友解决网络OPC通讯的问题,由于朋友所遇到的这种应用场景在目前的工业现场比较常见,因此就将处理这类应用场景的OPC通讯方法分享出来,希望能对在现场做工程的朋友有所帮助。

朋友在现场实施的项目是一个生产信息化的项目,需要从现场的各个控制子系统获取数据,比较好的是,各个控制子系统都都提供了OPCServer,朋友在前期的调试中,单独的已经都能和各个控制子系统的OPCServer通讯,获取到需要的数据了。但由于前期方案设计时,基于成本的考虑加上每个系统需要采集的测点很少(几十个吧),并未采用一个子系统一台接口机的方案。而现在到了具体的实施阶段,才发现在一台接口机上同时多个远程OPCServer的数据不是一件容易的事情。

遇到的问题如下:

1) 各个子系统提供OPCServer的计算机由不同的自动化集成商实施,也是不同的部门在管理和维护,难以让所有的OPCServer计算机都使用相同的用户名密码。

2) 各个子系统提供OPCServer的计算机操作系统也不一样,从Windows 2000到Window 7,各个版本都存在,很难都配置为允许匿名方式访问远程OPCServer。

3) 好不容易将能统一用户名密码的几个OPCServer统一了,结果又遭遇了子系统的电脑重装和操作系统密码被修改的事情,能通讯的也变得不能通讯了。

朋友在现场的3个月一般时间都在处理OPC通讯的问题都有些疯了。上周给我电话,问有啥好招能解决这个现场的OPC通讯问题不。

看完上面的情况,可能就有同学说了,每个子系统单独配置一台接口机或者网关不就ok了!是啊,能这样解决,大家都省心啊。可这个项目总金额本身就较低,原来做方案时就为了节省成本,加上每个子系统需要的数据不多,因此才采用一台接口机增加4块网卡同时采集3,5个OPCServer的方案,如变成一对一的方案,采购接口机的5,6万人民币从哪里出来。

买OPC产品的同学可能要说了,每台OPCServer计算机上增加一个OPC隧道软件不就绕开远程OPC需要用户登录验证的机制了吗?是啊,这也是一个好办法,早期给朋友建议过,结果甲方给否定了,说各个子系统都是不同的部门在维护,你在人家系统的计算机上安装你的软件,万一出现了死机或者系统故障问题,谁来承担这个责任,得一句话就把一个好的解决办法给否定了。

让子系统OPCServer所在的计算机的操作系统都使用相同用户名和密码难实现,一对一采集又增加成本,在每台OPCServer上安装OPC隧道软件也不行(至少这个现场的甲方不允许),那还有其他可行方案吗?

经验丰富的同学应该想出了办法,这里我将各种可行的办法整理汇总一下。

1.允许工程师去配置OPCServer计算机的,最好将OPCServer的DCOM都配置为交互访问方式,根据操作系统的情况,将XP,2003配置让匿名用户方式可访问。其他操作系统则在系统中添加固定的用户名和密码,同时在安全策略中设定此用户只能用户远程访问,而不能用户桌面登录。

2. 不允许工程师去配置OPCServer计算机的,现场子系统应该会有原厂家人员进行配置,可与现场子系统的原厂家人员沟通,按照1.中的方式进行配置。

3. 考虑到子系统的电脑不知道啥时候会被重装,一定要给甲方的系统维护人员留下详细的OPC通讯配置文档,以备不时之需。考虑到大多数的甲方维护人员是不会看这个苦涩的技术文档,最好将OPC通讯配置作出一个批处理文件,然后告诉维护人员,如果以后重装了,只需要在子系统的OPCServer的电脑上运行一下这个批处理就好了。这种方式,大多数的甲方维护人员都会乐意接受的。
 

--------------------------脚本开始----------------------

@echo off

::此脚本只支持自动配置Windows XP/2003系统上的OPCServer

TITLE 自动配置Windows XP/2003系统指定OPCServer的DCOM。
 

::----------------------------定义变量信息开始---------------------------------------------

::定义OPCServer的名称

set OPCServerName=Matrikon.OPC.Simulation.1
 

::定义OPCServer的进程名称,此进程的绝对路径

set OPCServerProcess=D:\OPCSim\OPCSim.exe

 

::定义远程访问OPCServer的用户名和密码

set newuser=opcuser

set newuserpwd=opcuser

 

::-----------------------定义变量信息结束-------------------
 

::————————————选择菜单——————————————

color 0A

 

:top

ECHO ==================================================================

echo ******************************************************************

echo OPCServer的名称: %OPCServerName%

echo OPCServer的进程名称及路径: %OPCServerProcess%

echo ******************************************************************

echo 新添加的用户名称: %newuser%

echo 新添加的用户密码: %newuserpwd%

echo ******************************************************************

ECHO ==================================================================

ECHO 核对上面的信息是否正确,准确无误按任意键继续。

ECHO 如果有误,输入x键并回车或直接关闭窗口,重新定义脚本中变量后再次运行。

ECHO ─────────────────────────────────

ECHO.

ECHO 1. 按回车键继续

ECHO 2. 按x键并回车后编辑脚本

ECHO.

 

:cho

SET Choice=

SET /P Choice=选择:

rem 设定变量"Choice"为用户输入的字符

IF NOT "%Choice%"=="" SET Choice=%Choice:~0,1%

rem 如果输入大于1位,取第1位,比如输入132,则返回值为1

ECHO.

IF /I "%Choice%" NEQ "x" GOTO gogogo

IF /I "%Choice%" EQU "x" GOTO endx

rem 为避免出现返回值为空或含空格而导致程序异常,需在变量外另加双引号

rem 注意,IF语句需要双等于号

ECHO 选择无效,请重新输入

ECHO.

GOTO top

 

pause

::——————————————美丽的分割——————————————————————

 

:gogogo

echo 开始配置OPCServer

 

echo 1)配置本地计算机的安全策略及启用guest用户

echo 在OPCServer服务器添加指定用户使远程计算机可以通过此用户访问OPCServer

::在OPCServer服务器添加指定用户和密码

net user %newuser% %newuserpwd% /add /passwordchg:no /expires:never

 

::指定新增加的用户是激活状态

net user %newuser% /active:yes

 

::将新增加的用户添加到管理员组中

net localgroup Administrators %newuser% /add

 

echo 2)配置本地计算机的安全策略及启用guest用户及设置新增加用户只能远程访问

::启用来宾用户

@net user guest /ACTIVE:YES

 

::设置来宾用户密码为空

@net user guest ""
 

::生成安全策略配置文件

echo [Unicode]>opc.inf

echo Unicode=yes>>opc.inf

 

echo [System Access]>>opc.inf

::用户密码永不过期

echo MinimumPasswordAge = 0>>opc.inf

echo MaximumPasswordAge = -1>>opc.inf
 

echo [Registry Values]>>opc.inf

 

::远程访问此计算机时的身份强制都是来宾用户

echo MACHINE\System\CurrentControlSet\Control\Lsa\ForceGuest=4,1>>opc.inf
 

::允许远程访问此计算机时的用户密码是空

echo MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse=4,1>>opc.inf

 

echo [Privilege Rights]>>opc.inf
 

::生成安全策略配置文件

echo SeDenyNetworkLogonRight = >>opc.inf
 

::禁止本地桌面登录的用户列表

echo SeDenyInteractiveLogonRight = SUPPORT_388945a0,%newuser%,Guest>>opc.inf

 

echo [Version]>>opc.inf

echo signature="$CHICAGO$">>opc.inf

echo Revision=1>>opc.inf

 

::使用secedit程序将本地计算机的安全策略配置文件导入当前系统

@secedit /configure /db opc.sdb /cfg opc.inf /log opc.log /quiet

@gpupdate /force
 

@ping 127.0.0.1 -n 1 >nul
 

::使用secedit程序将本地计算机的安全策略配置文件导入当前系统

@secedit /configure /db opc.sdb /cfg opc.inf /log opc.log /quiet

@gpupdate /force
 

del /Q opc.* 2>nul

 

@ping 127.0.0.1 -n 3 >nul

 

echo 3)配置DCOM为everyone可以访问

echo Windows Registry Editor Version 5.00 >>opc.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole] >>opc.reg

echo "DefaultLaunchPermission"=hex:01,00,04,80,70,00,00,00,80,00,00,00,00,00,00,00,\ >>opc.reg

echo 14,00,00,00,02,00,5c,00,04,00,00,00,00,00,18,00,1f,00,00,00,01,02,00,00,00,\ >>opc.reg

echo 00,00,05,20,00,00,00,20,02,00,00,00,00,14,00,1f,00,00,00,01,01,00,00,00,00,\ >>opc.reg

echo 00,01,00,00,00,00,00,00,14,00,1f,00,00,00,01,01,00,00,00,00,00,05,04,00,00,\ >>opc.reg

echo 00,00,00,14,00,1f,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00,01,02,00,00,\ >>opc.reg

echo 00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,\ >>opc.reg

echo 02,00,00 >>opc.reg

echo "MachineLaunchRestriction"=hex:01,00,04,80,48,00,00,00,58,00,00,00,00,00,00,00,\ >>opc.reg

echo 14,00,00,00,02,00,34,00,02,00,00,00,00,00,18,00,1f,00,00,00,01,02,00,00,00,\ >>opc.reg

echo 00,00,05,20,00,00,00,20,02,00,00,00,00,14,00,1f,00,00,00,01,01,00,00,00,00,\ >>opc.reg

echo 00,01,00,00,00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,\ >>opc.reg

echo 00,00,00,00,05,20,00,00,00,20,02,00,00 >>opc.reg

echo "MachineAccessRestriction"=hex:01,00,04,80,44,00,00,00,54,00,00,00,00,00,00,00,\ >>opc.reg

echo 14,00,00,00,02,00,30,00,02,00,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,\ >>opc.reg

echo 00,00,05,07,00,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,00,00,01,00,00,\ >>opc.reg

echo 00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,00,00,00,00,\ >>opc.reg

echo 05,20,00,00,00,20,02,00,00 >>opc.reg

echo "EnableDCOM"="Y" >>opc.reg

echo "DefaultAccessPermission"=hex:01,00,04,80,58,00,00,00,68,00,00,00,00,00,00,00,\ >>opc.reg

echo 14,00,00,00,02,00,44,00,03,00,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,\ >>opc.reg

echo 00,00,01,00,00,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,00,00,05,0a,00,\ >>opc.reg

echo 00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00,01,02,00,\ >>opc.reg

echo 00,00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,00,00,00,00,05,20,00,00,00,\ >>opc.reg

echo 20,02,00,00 >>opc.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat] >>opc.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat\ActivationSecurityCheckExemptionList] >>opc.reg

echo "{A50398B8-9075-4FBF-A7A1-456BF21937AD}"="1" >>opc.reg

echo "{AD65A69D-3831-40D7-9629-9B0B50A93843}"="1" >>opc.reg

echo "{0040D221-54A1-11D1-9DE0-006097042D69}"="1" >>opc.reg

echo "{2A6D72F1-6E7E-4702-B99C-E40D3DED33C3}"="1" >>opc.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\NONREDIST] >>opc.reg

echo "System.EnterpriseServices.Thunk.dll"="" >>opc.reg
 

@regedit /s opc.reg

 

echo 4)对本机的OPC Server进行配置

echo 对本机的OPC Server进行配置,请前面填写正确的OPC Server名称

::下面这句不要动

echo %OPCServerName%>%cd%\OPCname.txt

@ping 127.0.0.1 -n 2 >nul

for /F "tokens=*" %%a in (OPCname.txt) do for /F "skip=4 tokens=3" %%b IN ('reg query "HKEY_CLASSES_ROOT\%%a\CLSID"') DO @echo %%b & reg add "HKEY_CLASSES_ROOT\AppID\%%b" /v "RunAs" /t REG_SZ /d "Interactive User" /f & reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\%%b" /v "RunAs" /t REG_SZ /d "Interactive User" /f

 

echo 5)添加OPC相关程序到Windows 防火墙

netsh firewall set allowedprogram C:\WINDOWS\system32\Opcenum.exe opcenum enable

netsh firewall set allowedprogram %OPCServerProcess% opcserver enable

netsh firewall set portopening TCP 135 DCOM ENABLE

 

@ping 127.0.0.1 -n 1 >nul

del /Q OPCname.txt

del /Q opc.reg

:end

pause & exit
 

:endx

start notepad.exe %cd%\_OPCServer_DCOM配置脚本.cmd

exit
 

---------------------------------脚本结束-------------------