检查计算机上是否安装了Microsoft Security Essentials

时间:2013-10-04 20:39:31

标签: c# windows registry antivirus

所以我编写了这个安装程序脚本,它自动在目标机器上安装了几个不同的产品。有一次,我正在检查机器(Windows 7)是否安装了 Microsoft Security Essentials - 如果没有,那么我安装该程序。下面的代码是用C#编写的,但问题也可能适用于其他语言。

帮助那些回答的一些事实:

  • MSE在64位计算机上是64位,在32位计算机上是32位(有两个不同的安装程序)因此,注册表中的路径始终是: SOFTWARE \ Microsoft \ Windows \ CurrentVersion \卸载即可。
  • 自动安装的过程以管理员身份运行。我能够在同一目录中看到其他程序的密钥。

我在注册表编辑器中的视图:

enter image description here

我的方法:

private static bool DoesMseExist()
{
    string location = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(location))
    {
         foreach (string subKey in rk.GetSubKeyNames())
         {
              using (RegistryKey productKey = rk.OpenSubKey(subKey))
              {
                  if (productKey != null)
                  {                     
                      if (Convert.ToString(productKey.GetValue("DisplayName"))
                                       .Contains("Microsoft Security Client"))
                      {
                         return true;
                      }
                  }
              }
         }
     }
     return false;
}

这永远找不到钥匙。任何帮助发现原因都会受到高度赞赏。

暂时我使用以下作为替代品。

string MseLocation = @"C:\Program Files\Microsoft Security Client\msseces.exe";
return (File.Exists(MseLocation)); 

1 个答案:

答案 0 :(得分:0)

我目前正在使用.NET 4.0,它为从32位进程访问64位注册表提供了一个非常干净的解决方案。否则,如果您使用的是早期版本的Framework,那么您需要使用P / Invoke并使用RegOpenKeyEx中的 KEY_WOW64_64KEY 标志调用函数WINAPI,如上所述here

但是我使用过的解决方案。

private static bool DoesMseExist()
{
       using (RegistryKey localMachineX64View = 
                    RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
                    RegistryView.Registry64))
       {
           using (RegistryKey rk = localMachineX64View.OpenSubKey(location))
           {
               foreach (string subKey in rk.GetSubKeyNames())
               {
                   using (RegistryKey productKey = rk.OpenSubKey(subKey))
                   {
                       if (productKey != null)
                       {
                           if (Convert.ToString(productKey.GetValue("DisplayName"))
                              .Contains("Microsoft Security Client"))
                           {
                               return true;
                           }
                       }
                   }
               }
           }
      }
      return false;
}

我正在为这个问题编写一个P / Invoke解决方案,但后来我遇到了this。您需要做的就是使用RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64),您将克服注册表重定向。在我看来,与P / Invoke解决方案相比,这是一种非常容易理解和可读的方法。