1、先判断Windows系统防火墙服务是否在启用状态
使用System.ServiceProcess命名空间来检查Windows防火墙服务的状态。具体来说,你可以通过ServiceController类来获取服务的状态。以下是一个示例代码,用于检查Windows防火墙服务是否正在运行:
using System;
using System.ServiceProcess;
class Program
{
static void Main()
{
// Windows防火墙服务的名称
string serviceName = "MpsSvc"; // Windows Firewall服务的服务名称
// 创建ServiceController实例
using (ServiceController sc = new ServiceController(serviceName))
{
try
{
// 获取服务的状态
ServiceControllerStatus status = sc.Status;
// 判断服务是否正在运行
if (status == ServiceControllerStatus.Running)
{
Console.WriteLine("Windows防火墙服务正在运行。");
}
else
{
Console.WriteLine("Windows防火墙服务未运行。当前状态: " + status);
}
}
catch (InvalidOperationException ex)
{
Console.WriteLine("无法获取服务状态: " + ex.Message);
}
}
}
}
代码说明:
ServiceController:ServiceController类用于与Windows服务进行交互。你可以通过它来获取服务的状态、启动或停止服务等。
MpsSvc:这是Windows防火墙服务的服务名称。在Windows中,防火墙服务的名称是MpsSvc(Windows Firewall)。
ServiceControllerStatus:这是一个枚举,表示服务的状态。常见的状态包括Running(运行中)、Stopped(已停止)、Paused(已暂停)等。
运行结果:
如果Windows防火墙服务正在运行,程序将输出“Windows防火墙服务正在运行”。
如果服务未运行,程序将输出当前服务的状态(如“Stopped”)。
如果无法获取服务状态(例如服务不存在或权限不足),程序将捕获异常并输出错误信息。
注意事项:
通过这种方式,你可以判断Windows防火墙服务是否正在运行,并根据需要采取进一步的操作。
2、Windows系统防火墙服务已启用,但要判断是否使用中
先尝试通过 Windows 防火墙 API 使用 INetFwPolicy2 接口直接获取防火墙的启用状态,但试了无数次,始终报错:
无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“INetFwPolicy2”。此操作失败的原因是对 IID 为“{E2B3C97F-6AE1-41AC-817A-F6F92166D7DD}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。
无法解决以上报错,最终使用系统命令直接获取状态:
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
class FirewallChecker
{
static void Main()
{
CheckFirewallStatus();
}
static void CheckFirewallStatus()
{
try
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "netsh",
Arguments = "advfirewall show allprofiles",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
StandardOutputEncoding = System.Text.Encoding.UTF8 // 确保编码正确
};
using (Process p = Process.Start(psi))
{
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
// 优化点:使用正则表达式匹配状态
bool isDisabled = Regex.IsMatch(output, @"状态\s+关闭");
Console.WriteLine(isDisabled ? "防火墙已停用" : "防火墙已启用");
}
}
catch (Exception ex)
{
Console.WriteLine($"检测失败: {ex.Message}");
}
}
}
跨语言兼容性方案
如果需支持多语言系统(如英文/中文),可进一步改进:
// 匹配中英文状态关键词
bool isDisabled = Regex.IsMatch(output, @"(状态\s+关闭|State\s+OFF)", RegexOptions.IgnoreCase);
Console.WriteLine(isDisabled ? "防火墙已停用" : "防火墙已启用");
为什么这个方法更可靠?
1、绕过 COM 接口依赖
Windows 防火墙 COM 接口 (INetFwPolicy2
) 需要精确的接口定义和权限,而 netsh
命令是系统原生工具,稳定性更高。
2、避免动态类型转换问题
使用 dynamic
或接口强制转换时,易因系统版本差异失败,而命令行输出格式相对稳定。
3、直接反映用户界面状态
netsh
的输出与用户在“控制面板”中看到的状态完全一致,无需处理底层配置差异。
扩展建议
若需更精细控制(如检查各独立配置文件),可解析详细输出:
// 检查每个配置文件的独立状态
bool isDomainDisabled = Regex.IsMatch(output, @"域配置文件\s+状态\s+关闭");
bool isPrivateDisabled = Regex.IsMatch(output, @"专用配置文件\s+状态\s+关闭");
bool isPublicDisabled = Regex.IsMatch(output, @"公用配置文件\s+状态\s+关闭");
if (isDomainDisabled && isPrivateDisabled && isPublicDisabled)
{
Console.WriteLine("所有配置文件均未启用");
}
适用场景对比
方法 | 适用场景 | 缺点 |
---|
COM 接口 | 需要实时编程控制防火墙 | 依赖系统组件,易出错 |
注册表 | 需要快速读取配置 | 路径可能随系统更新变化 |
命令行解析 | 快速验证状态,避免复杂依赖 | 需处理字符串格式 |
最终的调整直击问题核心,通过简化逻辑避开了 COM 接口的复杂性,非常适合需要快速验证防火墙状态的场景!
该文章在 2025/3/15 0:06:49 编辑过