2013-10-04 53 views
0

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

一些事实,以协助那些应答:

  • MSE是在64位机器上的64位和32位机器32位(有两个不同的安装程序)因此,在该路径注册表总是:SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall
  • 自动安装的过程以管理员身份运行。我能够在同一个目录中看到其他程序的键。

我在注册表编辑器视图:

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)); 
+0

您是否为x86平台编译应用程序? – Steve

+1

不应该'字符串位置'使用'@'以及? –

+0

它的确如此。实际的代码使用一个常量。我会解决它。 –

回答

0

我目前使用.NET 4.0,它提供了一个非常干净的解决方案,用于从32位进程访问64位注册表。否则,如果您使用Framework的早期版本,那么您需要使用P/Invoke并使用中的KEY_WOW64_64KEY标志调用功能RegOpenKeyEx,如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解决方案相比,这是一种非常容易理解和易读的方法。

相关问题