VB.NET如何检测客户端‘文件和打印机共享’启用状态
VB.NET VPN场景下SQL Server连接前置校验实现方案
现有VPN检测逻辑优化
你当前写的VPN检测逻辑只匹配网卡名称,存在「网卡配置存在但实际未连通」的误判可能,补充网卡运行状态、类型判断即可,优化后代码如下:
Dim myInterfaceList As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces ' 同时校验网卡名称、运行状态、VPN网卡类型,避免误判 Dim myVPNRunning As Boolean = myInterfaceList.AsEnumerable().Any( Function(x) x.Name = "MyTestVPN" AndAlso x.OperationalStatus = OperationalStatus.Up AndAlso x.NetworkInterfaceType = NetworkInterfaceType.Ppp ) chkProgress3.Checked = myVPNRunning
文件和打印机共享状态检测实现
不需要调用PowerShell,纯VB.NET原生实现即可,兼容性更好,不会触发系统脚本拦截。文件和打印机共享正常启用需要同时满足两个条件:
- 活动网卡(含VPN虚拟网卡)绑定了「Microsoft 网络的文件和打印机共享」服务组件
- Windows防火墙放行了文件和打印机共享的对应入站规则
前置准备
在项目中添加COM引用:右键项目 → 「添加引用」→ 切换到COM标签页 → 找到并勾选Windows Firewall Helper Class Library,确认添加即可,该组件是Windows系统自带,无需额外安装。
检测代码
首先引入所需命名空间:
Imports Microsoft.Win32 Imports System.Net.NetworkInformation Imports NetFwTypeLib
核心检测函数:
''' <summary> ''' 检测活动网络下文件和打印机共享是否正常启用 ''' </summary> ''' <returns>True=启用正常,False=未启用/配置异常</returns> Private Function CheckFileAndPrinterSharingEnabled() As Boolean Dim serviceBinded As Boolean = False Dim firewallRuleAllowed As Boolean = False ' 文件和打印机共享服务组件固定GUID Const SHARING_SERVICE_GUID As String = "{4D36E978-E325-11CE-BFC1-08002BE10318}" ' 网卡设备类固定GUID Const NETWORK_ADAPTER_CLASS_GUID As String = "{4d36e972-e325-11ce-bfc1-08002be10318}" ' 1. 遍历所有已连接的网卡,检查是否绑定共享服务 Dim activeAdapters = NetworkInterface.GetAllNetworkInterfaces() _ .Where(Function(i) i.OperationalStatus = OperationalStatus.Up).ToList() Using adapterRootKey As RegistryKey = Registry.LocalMachine.OpenSubKey( $"SYSTEM\CurrentControlSet\Control\Class\{NETWORK_ADAPTER_CLASS_GUID}") If adapterRootKey IsNot Nothing Then For Each subKeyName In adapterRootKey.GetSubKeyNames() Using adapterKey As RegistryKey = adapterRootKey.OpenSubKey(subKeyName) If adapterKey Is Nothing Then Continue For Dim instanceId = TryCast(adapterKey.GetValue("NetCfgInstanceId"), String) If String.IsNullOrEmpty(instanceId) Then Continue For ' 匹配当前活动网卡 If activeAdapters.Any(Function(a) a.Id = instanceId) Then Dim bindEntries = TryCast( adapterKey.OpenSubKey("Ndi\Interfaces")?.GetValue("LowerRangeBindings"), String() ) If bindEntries IsNot Nothing AndAlso bindEntries.Contains(SHARING_SERVICE_GUID) Then serviceBinded = True Exit For End If End If End Using If serviceBinded Then Exit For Next End If End Using ' 2. 检查防火墙是否放行共享规则 Try Dim fwPolicy As INetFwPolicy2 = Activator.CreateInstance( Type.GetTypeFromProgID("HNetCfg.FwPolicy2") ) Dim activeProfile = fwPolicy.CurrentProfileTypes For Each rule As INetFwRule In fwPolicy.Rules ' 通过系统内置规则组标识匹配,兼容多语言系统 If rule.Grouping = "@FirewallAPI.dll,-28502" _ AndAlso rule.Enabled _ AndAlso (rule.Profiles And activeProfile) > 0 Then firewallRuleAllowed = True Exit For End If Next Catch ' 权限不足时返回失败,提示用户以管理员身份运行程序 Return False End Try Return serviceBinded AndAlso firewallRuleAllowed End Function
调用方式
在发起SQL Server连接请求前插入校验逻辑即可:
Dim sharingOk As Boolean = CheckFileAndPrinterSharingEnabled() chkProgress4.Checked = sharingOk If Not sharingOk Then MessageBox.Show("文件和打印机共享未正常启用,VPN环境下无法发现并连接SQL Server,请启用后重试", "前置校验不通过", MessageBoxButtons.OK, MessageBoxIcon.Warning) Return End If
方案说明
- 适配Win7至Win11全版本Windows系统,非域环境完全可用,不依赖组策略配置
- 无PowerShell调用带来的版本兼容、执行权限拦截问题,运行稳定性更高
- 同时校验网卡绑定、防火墙规则两个维度,避免单维度检测的误判问题(很多场景下用户开了网卡绑定但防火墙拦截,依然无法正常访问SQL Server)
- 如果检测时提示权限不足,可以给程序添加应用程序清单文件,配置
requestedExecutionLevel为requireAdministrator,要求程序启动时申请管理员权限即可。
内容的提问来源于stack exchange,提问作者Tim Hutchinson
相关产品推荐
相关产品推荐

