如何使用WMI或其他方法在C++中检测安装在Windows 2003服务器、2008服务器、2003服务器R2和2008服务器R2上的防病毒软件。

3

我使用WMI来检测操作系统上是否存在防病毒软件,它可以在Win XP和Win7上正常工作,并显示有关防病毒软件的信息,如名称和实例ID,使用的命名空间为:\root\SecurityCenter和\root\SecurityCenter2,\root\Security。

if(isHLOSVersion( ))

 hres = pLoc->ConnectServer( _bstr_t(L"root\\SecurityCenter2"),
 // Object path of SecurityCenter 

 NULL,                    // User name. NULL = current user 

         NULL,                    // User password. NULL = current 

         0,                       // Locale. NULL indicates current 

         NULL,                    // Security flags. 

         0,                       // Authority (e.g. Kerberos) 

         0,                       // Context object  

         &pSvc                    // pointer to IWbemServices proxy 

         ); 
 else
  hres = pLoc->ConnectServer( _bstr_t(L"root\\SecurityCenter"),
 // Object path of SecurityCenter 

   NULL,                    // User name. NULL = current user 

         NULL,                    // User password. NULL = current 

         0,                       // Locale. NULL indicates current 

         NULL,                    // Security flags. 

         0,                       // Authority (e.g. Kerberos) 

         0,                       // Context object  

         &pSvc                    // pointer to IWbemServices proxy 

         ); 

但是,在 Windows 2003 Server 和 2008 Server、2003 Server R2 和 2008 Server R2 中,上述名称空间不存在,因此这种方法无法使用。

请告诉我如何检测 Windows 2003 Server 和 2008 Server、2003 Server R2 和 2008 Server R2 操作系统中是否存在防病毒软件。


请在输入代码示例时使用代码标记,否则没有人会尝试阅读它的当前状态。 - Adrian Fâciu
1个回答

2

该命名空间在Windows Server平台上不可用,我认为它可能已被弃用(即即将消失)。

您可以使用WscGetSecurityProviderHealth()来获得相同的结果。

请参见http://msdn.microsoft.com/en-us/library/bb432506.aspx

这是我的一个微不足道的示例,似乎可以正常工作:

#define _WIN32_WINNT _WIN32_WINNT_WIN7
#include <Windows.h>
#include <Wscapi.h>
#include <iostream>

#pragma comment(lib, "Wscapi")


int main(int argc, char* argv[])
{
   WSC_SECURITY_PROVIDER_HEALTH health;
   const DWORD dwAntivirus(WSC_SECURITY_PROVIDER_ANTIVIRUS);

   HRESULT hr = WscGetSecurityProviderHealth(dwAntivirus, &health);
   if (FAILED(hr))
   {
      std::cerr << "Error " << std::hex 
                << std::showbase << hr << "\n";
      return -1;
   }
   switch (health)
   {
      case WSC_SECURITY_PROVIDER_HEALTH_GOOD:
         std::cout << "Antivirus health is good\n";
         return 0;
      case WSC_SECURITY_PROVIDER_HEALTH_NOTMONITORED:
         std::cout << "Antivirus health is not monitored\n";
         return 1;
      case WSC_SECURITY_PROVIDER_HEALTH_POOR:
         std::cout << "Antivirus health is poor\n";
         return 2;
      case WSC_SECURITY_PROVIDER_HEALTH_SNOOZE:
         std::cout << "Antivirus health is snooze\n";
         return 3;
      default:
         std::cout << "Unexpected antivirus health value: "
                   << std::hex << std::showbase 
                   << health << "\n";
         return 4;
   }
}

2012年12月9日更新

Alex指出(下面有),这在Windows Server上不起作用,只适用于Windows工作站版本。 经过深思熟虑,我想到这可能是故意的,并且实际上可能是最好的。

应用程序真的需要知道服务器的状态吗? 大多数服务器安全程序在失败时都有设置警报的机制。 管理员将监视这些警报并修复损坏的内容。 应用程序应该像安全功能完全正常一样运行。

如果您确实必须了解特定程序的情况,可以在进程中查找其exe名称,并查看进程是否正在运行并且正在消耗CPU(未挂起)。 除此之外,您可能需要与安全程序的供应商合作:他们可能有一个API来查询程序。


根据您发布的文章,该函数仅适用于桌面应用程序,不支持服务器。 - athom
@Alex - 你说得对 -- 我错了。实际上,那很有道理。服务器安全确实与工作站安全不同。我怀疑很少有服务器运行消费级安全程序。 - Michael J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接