Posted By

jimfred on 12/07/08


Tagged

Enumeration registry Linq


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

umang_nine


GetSubKeys - static function provides recursive access to registry keys with LINQ queries or foreach loops


 / Published in: C#
 

URL: See URLs in comments in function

This static function allows LINQ or foreach access to registry keys to search for keys, value names and/or values. See example usage in . This was created to find occurrences of driver references ( MyDriver.sys and corresponding OEMnnn.INF) in the registry.

LINQ access to the registry provides for fancy conditions in where-clauses. Try/catch blocks are used to handle (ignore) access exceptions.

  1. /// <summary>
  2. /// Given a registry key, get a list of child sub-keys.
  3. /// This function recursively calls itself.
  4. /// Intended to be used in an implementation of recursive enumeration in
  5. /// either a foreach loop or a LINQ expression.
  6. /// If access to a key is not allowed, such subkeys are not included in the list and
  7. /// a Debug.WriteLine prints the key name.
  8. /// <example>
  9. /// string searchString = "dll".ToLower(); // Example search for mention of dll. 'ToLower' is used for non-case-sensisitve search.
  10. /// Microsoft.Win32.RegistryKey keyStart = rkLm.OpenSubKey(@"SOFTWARE\Adobe\");
  11. ///
  12. /// // LINQ expression to retrieve a list of strings based on the 'where' condition.
  13. /// IEnumerable<string> regVals2 =
  14. /// // These two 'from' clauses allow nested enumeration of keys and their values.
  15. /// from key in GetSubKeys(keyStart)
  16. /// from valueName in key.GetValueNames()
  17. /// // create a string 'value' for convenient access to value.
  18. /// let value = key.GetValue(valueName).ToString()
  19. /// where
  20. /// // this example where clause searches for searchString.
  21. /// // and of course could be enhanced to narrow search results.
  22. /// // 'ToLower' is used for non-case-sensisitve search.
  23. /// value.ToLower().Contains(searchString) ||
  24. /// valueName.ToLower().Contains(searchString) ||
  25. /// key.Name.ToLower().Contains(searchString)
  26. /// // format a string containing the key name, value name and value.
  27. /// // Hint: call a member function here to allow setting of break points.
  28. /// select string.Format("{0}: {1}={2}", key.Name, valueName.ToString(), value);
  29. /// </example>
  30. /// </summary>
  31. /// <param name="keyParentArg">A registry key</param>
  32. /// <returns>An IEnumerable List of subkeys under the keyParentArg.</returns>
  33. static IEnumerable<Microsoft.Win32.RegistryKey> GetSubKeys(Microsoft.Win32.RegistryKey keyParentArg)
  34. {
  35. // This link... http://www.csharphelp.com/archives2/archive430.html
  36. // ...has a GetSubKeys implementation without try/catch.
  37. // Omitting try/catch will cause LINQ expressions to abort prematurely.
  38. // This link... http://support.microsoft.com/kb/267908 -
  39. // ...has an example that enumerates using advapi32.dll without .NET or LINQ.
  40. // This link... http://blog.domaindotnet.com/2008/09/08/the_fastest_dot_net_hash_set_collection_with_linq_extended_features/
  41. // ...has an alternative implementation (using GetAllSubkeys and TryOpenSubKey) that
  42. // I thought was more complex than necessary for simple registry enumeration. This
  43. // GetSubKeys function provides similar functionality with one function.
  44.  
  45. // This list will be built as subkeys are added.
  46. List<Microsoft.Win32.RegistryKey> keysFound = new List<Microsoft.Win32.RegistryKey>();
  47.  
  48. try
  49. {
  50. if (keyParentArg.SubKeyCount > 0)
  51. {
  52. foreach (string strKeyChild in keyParentArg.GetSubKeyNames())
  53. {
  54. try
  55. {
  56. Microsoft.Win32.RegistryKey keyChild = keyParentArg.OpenSubKey(strKeyChild);
  57. if (keyChild != null)
  58. {
  59. keysFound.Add(keyChild);
  60.  
  61. // Recursive call back into this method
  62. IEnumerable<Microsoft.Win32.RegistryKey> keyGrandChildren = GetSubKeys(keyChild);
  63.  
  64. if (keyGrandChildren != null)
  65. {
  66. keysFound.AddRange(keyGrandChildren);
  67. }
  68. else
  69. {
  70. System.Diagnostics.Debug.Assert(false);
  71. }
  72. } // if not null.
  73. }
  74. catch (Exception ex)
  75. {
  76. System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + " failed trying " + strKeyChild + " in " + keyParentArg);
  77. }
  78. } // foreach
  79. } // if
  80. }
  81. catch (Exception ex)
  82. {
  83. System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + " failed trying " + keyParentArg);
  84. }
  85.  
  86. return keysFound;
  87. } // GetSubKeys()

Report this snippet  

You need to login to post a comment.