所以我编写了这个安装程序脚本,它自动在目标机器上安装了几个不同的产品。有一次,我正在检查机器(Windows 7)是否安装了 Microsoft Security Essentials - 如果没有,那么我安装该程序。下面的代码是用C#编写的,但问题也可能适用于其他语言。
帮助那些回答的一些事实:
我在注册表编辑器中的视图:
我的方法:
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 :(得分: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解决方案相比,这是一种非常容易理解和可读的方法。