.NET6下C#控制台可连OPC DA,Blazor Server连接失败原因排查
问题描述
使用OPCLabs库连接OPC DA服务器时,.NET6环境下的C#控制台应用可正常完成服务器浏览、节点遍历及数据读取操作,但将相同代码(包含安全配置参数)部署在同一服务器的ASP.NET Core Blazor Server(.NET6)应用中时,执行服务器浏览和节点浏览操作均报错,错误信息为:Browse_node_Error: The COM server does not support the interface 'OpcRcw.Da.IOPCServer'
需排查问题根源(是否与Web应用运行账户相关)并给出解决办法。
复现代码
using OpcLabs.EasyOpc; using OpcLabs.EasyOpc.DataAccess; using OpcLabs.EasyOpc.DataAccess.AddressSpace; using OpcLabs.EasyOpc.OperationModel; using OpcLabs.EasyOpc.OperationModel; using OpcLabs.EasyOpc.DataAccess.OperationModel; using OpcLabs.BaseLib.Runtime.InteropServices; using System.Diagnostics; Connect_OPCDA(); static void Connect_OPCDA() { ComManagement.Instance.Configuration.InstantiationParameters.OverrideDefaultSecurity = false; ComManagement.Instance.Configuration.SecurityParameters.UseCustomSecurity = true; ComManagement.Instance.Configuration.SecurityParameters.TurnOffCallSecurity = true; Browse_Servers(); Browse_nodes(); } static void Browse_Servers() { var client = new EasyDAClient(); ServerElementCollection serverElements; try { serverElements = client.BrowseServers("10.92.120.174"); } catch (OpcException opcException) { Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message); return; } foreach (ServerElement serverElement in serverElements) { Console.WriteLine($"ServerElements(\"{serverElement.ClsidString}\").ProgId: {serverElement.ProgId}"); } } static void Browse_nodes() { // Instantiate the client object. var client = new EasyDAClient(); DANodeElementCollection branchElements; try { //client.InstanceParameters.EnableNativeClient = false; branchElements = client.BrowseBranches("10.92.120.174", "OPC.IwSCP.1", ""); Console.WriteLine(branchElements); } catch (OpcException opcException) { Console.WriteLine("*** Failure Brose Nodes: {0}", opcException.GetBaseException().Message); Console.ReadLine(); return; } foreach (DANodeElement branchElement in branchElements) { Console.WriteLine($"BranchElements(\"{branchElement.Name}\").HasChildren: {branchElement.HasChildren}"); Console.WriteLine($"BranchElements(\"{branchElement.Name}\").HasChildren: {branchElement.HasChildren}"); } }
问题分析与解决方案
核心原因
问题本质与Blazor Server的运行账户权限及COM/OPC DA的权限机制直接相关:
- 控制台应用默认以当前登录用户身份运行,该用户通常已被授予访问OPC DA COM服务器的权限;而Blazor Server默认以IIS应用池账户(如
IIS AppPool\DefaultAppPool)或Kestrel的启动账户运行,这类账户权限受限,无法访问COM接口或远程OPC资源。 - OPC DA基于COM技术,
OpcRcw.Da.IOPCServer接口的访问需要客户端账户具备读取COM注册表、实例化COM对象的权限,应用池账户默认缺少这些权限。 - OPC DA服务器的DCOM配置未对Blazor Server运行账户开放,导致无法获取目标接口。
解决办法
1. 更换Blazor Server的运行账户
- IIS托管场景:
- 打开IIS管理器,定位到目标应用对应的应用池
- 右键选择「高级设置」,在「进程模型」->「标识」中选择「自定义账户」
- 输入具备OPC DA访问权限的本地/域用户凭据(即控制台应用运行时的用户)
- Kestrel自托管场景:
- 以有权限的用户身份启动Blazor Server应用,或在代码中指定运行账户(需管理员权限)。
2. 配置DCOM权限
- 运行
dcomcnfg打开「组件服务」 - 展开「组件服务」->「计算机」->「我的电脑」->「DCOM配置」
- 找到目标OPC DA服务器(如
OPC.IwSCP.1),右键选择「属性」 - 在「安全」选项卡中:
- 为Blazor Server的运行账户添加「启动和激活权限」、「访问权限」的允许权限
- 确保「配置权限」中该账户拥有读取权限
- 若访问远程OPC服务器,需在远程服务器重复上述配置,并确保防火墙开放DCOM端口(默认135及动态端口范围)。
3. 调整OPCLabs安全参数
修改代码中的安全配置,适配Web应用的COM访问场景:
ComManagement.Instance.Configuration.InstantiationParameters.OverrideDefaultSecurity = true; ComManagement.Instance.Configuration.SecurityParameters.UseCustomSecurity = false; // 设置合适的模拟级别 ComManagement.Instance.Configuration.SecurityParameters.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
同时尝试启用OPCLabs原生客户端模式:
client.InstanceParameters.EnableNativeClient = true; // 使用原生COM客户端适配OPC DA
4. 验证COM接口注册
以管理员身份运行命令提示符,执行以下命令确保OPC DA RCW组件注册成功:
regasm OpcRcw.Da.dll
(若找不到OpcRcw.Da.dll,可在OPCLabs安装目录或项目依赖包路径中查找)
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

