如何在注册表项中搜索特定值

时间:2008-11-17 10:22:48

标签: c# registry

如何在注册表项中搜索特定值?

例如,我想在

中搜索XXX
HKEY_CLASSES_ROOT\Installer\Products

C#中的任何代码示例都将受到赞赏,

感谢

4 个答案:

答案 0 :(得分:18)

如果你不想依赖LogParser(虽然功能强大):我会看一下Microsoft.Win32.RegistryKey类(MSDN)。使用OpenSubKey打开HKEY_CLASSES_ROOT \ Installer \ Products,然后调用GetSubKeyNames以获取子项的名称。

依次打开每一个,调用GetValue获取您感兴趣的值(我猜是ProductName),并将结果与​​您要查找的内容进行比较。

答案 1 :(得分:11)

帮助here ...

微软有一个很棒的(但并不为人熟知的)工具 - 名为LogParser

它使用SQL引擎查询所有类型的基于文本的数据,如Registry, 文件系统,事件日志,AD等...... 要从C#中使用,您需要从中构建一个Interop程序集 使用以下Logparser.dll COM服务器(调整LogParser.dll路径) 命令。

tlbimp "C:\Program Files\Log Parser 2.2\LogParser.dll"
/out:Interop.MSUtil.dll

以下是一个小样本,说明了如何查询Value 'HKLM \ SOFTWARE \ Microsoft树中的'VisualStudio'。

using System;
using System.Runtime.InteropServices;
using LogQuery = Interop.MSUtil.LogQueryClass;
using RegistryInputFormat = Interop.MSUtil.COMRegistryInputContextClass;
using RegRecordSet = Interop.MSUtil.ILogRecordset;

class Program
{
public static void Main()
{
RegRecordSet rs = null;
try
{
LogQuery qry = new LogQuery();
RegistryInputFormat registryFormat = new RegistryInputFormat();
string query = @"SELECT Path from \HKLM\SOFTWARE\Microsoft where
Value='VisualStudio'";
rs = qry.Execute(query, registryFormat);
for(; !rs.atEnd(); rs.moveNext())
Console.WriteLine(rs.getRecord().toNativeString(","));
}
finally
{
rs.close();
}
}
}

答案 2 :(得分:1)

此方法将在指定的注册表项中搜索包含指定值的第一个子项。如果找到密钥,则返回指定的值。 Searchign仅有一个级别的深度。如果您需要更深入的搜索,那么我建议修改此代码以使用递归。搜索区分大小写,但是如果需要,您可以再次修改。

private string SearchKey(string keyname, string data, string valueToFind, string returnValue)
{
    RegistryKey uninstallKey = Registry.LocalMachine.OpenSubKey(keyname);
    var programs = uninstallKey.GetSubKeyNames();

    foreach (var program in programs)
    {
        RegistryKey subkey = uninstallKey.OpenSubKey(program);
        if (string.Equals(valueToFind, subkey.GetValue(data, string.Empty).ToString(), StringComparison.CurrentCulture))
        {
            return subkey.GetValue(returnValue).ToString();
        }
    }

    return string.Empty;
}

示例用法

// This code will find the version of Chrome (32 bit) installed
string version = this.SearchKey("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "DisplayName", "Google Chrome", "DisplayVersion");

答案 3 :(得分:0)

@Caltor您的解决方案给了我我想要的答案。我欢迎改进或不涉及注册表的完全不同的解决方案。我正在Windows 10上的企业应用程序中使用已加入Azure AD的设备。我希望/需要在UWP应用中将Windows Hello用于设备和HoloLens 2。我的问题一直是从Windows 10获取AAD userPrincipal名称。经过几天的搜索和尝试了大量代码后,我在Windows注册表中的“当前用户”项中搜索了我的AAD帐户,并找到了它。通过一些研究,似乎该信息是特定的密钥。因为您可以加入多个目录,所以可能会有多个条目。我没有尝试解决该问题,而是使用AAD租户ID来解决。我只需要AAD userPrincipal名称。 我的解决方案消除了返回列表的重复,以便获得唯一的userPrincipal名称列表。应用程序用户可能必须选择一个帐户,即使HoloLens也可以接受。

using Microsoft.Win32;
using System.Collections.Generic;
using System.Linq;

namespace WinReg
{
  public class WinRegistryUserFind
  {
    // Windows 10 apparently places Office/Azure AAD in the registry at this location
    // each login gets a unique key in the registry that ends with the aadrm.com and the values
    // are held in a key named Identities and the value we want is the Email data item.
    const string regKeyPath = "SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\MSIPC";
    const string matchOnEnd = "aadrm.com";
    const string matchKey = "Identities";
    const string matchData = "Email";

    public static List<string> GetAADuserFromRegistry()
    {
      var usersFound = new List<string>();
      RegistryKey regKey = Registry.CurrentUser.OpenSubKey(regKeyPath);
      var programs = regKey.GetSubKeyNames();
      foreach (var program in programs)
      {
        RegistryKey subkey = regKey.OpenSubKey(program);
        if(subkey.Name.EndsWith(matchOnEnd))
        {
          var value = (subkey.OpenSubKey(matchKey) != null)? (string)subkey.OpenSubKey(matchKey).GetValue(matchData): string.Empty;
          if (string.IsNullOrEmpty(value)) continue;
          if((from user in usersFound where user == value select user).FirstOrDefault() == null)
            usersFound.Add(value) ;
        }
      }

      return usersFound;
    }
  }
}