有没有办法使用 C# 检测机器中是否安装了防病毒软件?我知道安全中心会检测到防病毒软件,但是如何在 C# 中检测到呢?
3 回答
据微软称,Windows 安全中心使用两层方法检测状态。一层是手动的,另一层是通过 Windows Management Instrumentation (WMI) 自动完成的。在手动检测模式下,Windows 安全中心搜索由独立软件制造商提供给 Microsoft 的注册表项和文件。这些注册表项和文件让 Windows 安全中心可以检测独立软件的状态。在 WMI 模式下,软件制造商确定自己的产品状态,并通过 WMI 提供程序将该状态报告回 Windows 安全中心。在这两种模式下,Windows 安全中心都会尝试确定以下是否为真:
存在防病毒程序。
防病毒签名是最新的。
为防病毒程序打开实时扫描或读写扫描。
对于防火墙,Windows 安全中心会检测是否安装了第三方防火墙以及防火墙是否打开。
所以为了确定杀毒软件的存在,可以使用WMI与root\SecurityCenter
命名空间建立连接(从windows Vista开始必须使用root\SecurityCenter2
命名空间),然后查询AntiVirusProduct
WMI类。
看这个示例代码
using System;
using System.Text;
using System.Management;
namespace ConsoleApplication1
{
class Program
{
public static bool AntivirusInstalled()
{
string wmipathstr = @"\\" + Environment.MachineName + @"\root\SecurityCenter";
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipathstr, "SELECT * FROM AntivirusProduct");
ManagementObjectCollection instances = searcher.Get();
return instances.Count > 0;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return false;
}
public static void Main(string[] args)
{
bool returnCode = AntivirusInstalled();
Console.WriteLine("Antivirus Installed " + returnCode.ToString());
Console.WriteLine();
Console.Read();
}
}
}
用记事本打开C:\Windows\System32\wbem\wscenter.mof
。它可以帮助您存在哪些命名空间和类:
C# 查询:
// SELECT * FROM AntiVirusProduct
// SELECT * FROM FirewallProduct
// SELECT * FROM AntiSpywareProduct
ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\SecurityCenter2", "SELECT * FROM AntiVirusProduct");
ManagementObjectCollection data = wmiData.Get();
foreach (ManagementObject virusChecker in data)
{
var virusCheckerName = virusChecker["displayName"];
}
wscenter.mof:
#pragma autorecover
#pragma classflags(64)
#pragma namespace("\\\\.\\root")
[NamespaceSecuritySDDL("O:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464G:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464D:(A;CI;0x1;;;BU)(A;CI;0x1;;;BA)(A;CI;0x1;;;NS)(A;CI;0x1;;;LS)(A;CI;0x1;;;AU)(A;CI;0x6001D;;;S-1-5-80-3232712927-1625117661-2590453128-1738570065-3637376297)")]
Instance of __namespace
{
Name = "SecurityCenter";
};
[NamespaceSecuritySDDL("O:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464G:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464D:(A;CI;0x1;;;BU)(A;CI;0x1;;;BA)(A;CI;0x1;;;NS)(A;CI;0x1;;;LS)(A;CI;0x1;;;AU)(A;CI;0x6001D;;;S-1-5-80-3232712927-1625117661-2590453128-1738570065-3637376297)")]
Instance of __namespace
{
Name = "SecurityCenter2";
};
#pragma namespace("\\\\.\\root\\SecurityCenter")
class AntiVirusProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
[Not_Null] boolean productUptoDate;
boolean onAccessScanningEnabled;
boolean productHasNotifiedUser;
boolean productWantsWscNotifications;
uint8 productState;
string companyName;
string versionNumber;
string pathToSignedProductExe;
};
class FirewallProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
boolean enabled;
boolean productHasNotifiedUser;
boolean productWantsWscNotifications;
uint8 productState;
string companyName;
string versionNumber;
string pathToSignedProductExe;
};
class AntiSpywareProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
[Not_Null] boolean productUptoDate;
boolean productEnabled;
boolean productHasNotifiedUser;
boolean productWantsWscNotifications;
uint8 productState;
string companyName;
string versionNumber;
string pathToSignedProductExe;
};
#pragma namespace("\\\\.\\root\\SecurityCenter2")
class AntiVirusProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
[Not_Null] string pathToSignedProductExe;
[Not_Null] string pathToSignedReportingExe;
[Not_Null] uint32 productState;
string timestamp;
};
class FirewallProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
[Not_Null] string pathToSignedProductExe;
[Not_Null] string pathToSignedReportingExe;
[Not_Null] uint32 productState;
string timestamp;
};
class AntiSpywareProduct
{
[key,Not_Null] string instanceGuid;
[Not_Null] string displayName;
[Not_Null] string pathToSignedProductExe;
[Not_Null] string pathToSignedReportingExe;
[Not_Null] uint32 productState;
string timestamp;
};
#pragma autorecover
WMI 查询在 Vista SP2 及更高版本中略有变化。
试试这部分 \root\SecurityCenter2 而不是 \root\SecurityCenter
结果也略有不同。您仍然可以获得显示名称,但您需要对 ProductState 字段进行一些位屏蔽,以确定是否启用/禁用了 onAccessScanner 以及 upToDate 类型的信息。