How to search for specific value in Registry keys

后端 未结 4 741
暗喜
暗喜 2020-12-15 12:19

How can I search for specific value in the registry keys?

For example I want to search for XXX in

HKEY_CLASSES_ROOT\\Installer\\Products


        
相关标签:
4条回答
  • 2020-12-15 12:37

    Help here...

    Microsoft has a great (but not well known) tool for this - called LogParser

    It uses a SQL engine to query all kind of text based data like the Registry, the Filesystem, the eventlog, AD etc... To be usable from C#, you need to build an Interop Assembly from the Logparser.dll COM server using following (adjust LogParser.dll path) command.

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

    Following is a small sample, that illustrates how to query for the Value 'VisualStudio' in the \HKLM\SOFTWARE\Microsoft tree.

    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();
    }
    }
    }
    
    0 讨论(0)
  • 2020-12-15 12:39

    In case you don't want to take a dependency on LogParser (as powerful as it is): I would take a look at the Microsoft.Win32.RegistryKey class (MSDN). Use OpenSubKey to open up HKEY_CLASSES_ROOT\Installer\Products, and then call GetSubKeyNames to, well, get the names of the subkeys.

    Open up each of those in turn, call GetValue for the value you're interested in (ProductName, I guess) and compare the result to what you're looking for.

    0 讨论(0)
  • 2020-12-15 12:41

    @Caltor your solution gave me the answer I was looking for. I welcome improvements or a completely different solution that does not involve the registry. I am working with enterprise applications on Windows 10 with devices joined to Azure AD. I want/need to use Windows Hello for devices and for HoloLens 2 in a UWP app. My problem has been getting the AAD userPrincipal name from Windows 10. After a couple days searching and trying lots of code I searched the Windows Registry for my AAD account in the Current User key and found it. With some research it appears that this information is in a specific key. Because you can be joined to multiple directories there may be more than one entry. I was not trying to solve that issue, that is done with the AAD tenant Id. I just needed the AAD userPrincipal name. My solution de-dups the return list so that I have a list of unique userPrincipal names. App users may have to select an account, this is tolerable for even 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;
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-15 12:47

    This method will search a specified registry key for the first subkey that contains a specified value. If the key is found then the specified value is returned. Searchign is only one level deep. If you require deeper searching then I suggest modifying this code to make use of recursion. Searching is case-sensitive but again you can modify that if required.

    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;
    }
    

    Example usage

    // 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");
    
    0 讨论(0)
提交回复
热议问题