Iterate through registry entries - c#

As suggested here, I need to iterate through entries in
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
to find out the installed path of my application. How to iterate so that I can find out the
InstallLocation value given the DisplayName. How to do it efficiently in C#.

Below is code to achieve your goal:
using Microsoft.Win32;
class Program
{
static void Main(string[] args)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
foreach (var v in key.GetSubKeyNames())
{
Console.WriteLine(v);
RegistryKey productKey = key.OpenSubKey(v);
if (productKey != null)
{
foreach (var value in productKey.GetValueNames())
{
Console.WriteLine("\tValue:" + value);
// Check for the publisher to ensure it's our product
string keyValue = Convert.ToString(productKey.GetValue("Publisher"));
if (!keyValue.Equals("MyPublisherCompanyName", StringComparison.OrdinalIgnoreCase))
continue;
string productName = Convert.ToString(productKey.GetValue("DisplayName"));
if (!productName.Equals("MyProductName", StringComparison.OrdinalIgnoreCase))
return;
string uninstallPath = Convert.ToString(productKey.GetValue("InstallSource"));
// Do something with this valuable information
}
}
}
Console.ReadLine();
}
}
Edit: See this method for a more comprehensive way to find an Applications Install Path, it demonstrates the using disposing as suggested in the comments.
https://stackoverflow.com/a/26686738/495455

using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"Whater\The\Key"))
{
if (key != null)
{
foreach (string ValueOfName in key.GetValueNames())
{
try
{
bool Value = bool.Parse((string)key.GetValue(ValueOfName));
}
catch (Exception ex) {}
}
}
}
With a bool cast :D - so the string is expected to be True or False.
For the user registry hive use Registry.CurrentUser instead of Registry.LocalMachine

Related

Is there a way to call registry ONLY one time and extract various keys values

I am basically reading below registry path,
SOFTWARE\\WOW6432Node\\Microsoft
But I have different sub keys and keys to read.
example
Version under SOFTWARE\\WOW6432Node\\Microsoft\\DataAccess
NodePath9 under SOFTWARE\\WOW6432Node\\Microsoft\\ENROLLMENTS\\ValidNodePaths
etc.
Currently I am able to read it one-by-one, but what are the ways so that I need to go the registry ONLY one time and I can do all other manipulation in C# code?
Can I read all information at once (so that ONLY one call to registry) till SOFTWARE\\WOW6432Node\\Microsoft and do rest work in C# code?
var X1 = GetRegistryValue("SOFTWARE\\WOW6432Node\\Microsoft\\DataAccess", "Version");
var X2 = GetRegistryValue("SOFTWARE\\WOW6432Node\\Microsoft\\ENROLLMENTS\\ValidNodePaths", "NodePath9");
private static string GetRegistryValue(string subKey, string keyName)
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subKey))
{
if (key != null)
{
if (key.GetValue(keyName) != null)
{
return (string)key.GetValue(keyName);
}
}
return null;
}
}
The OpenSubKey() method returns a registry key, so you could create a common one first and then pass it into the GetRegistryValue()...
private static RegistryKey GetCommonKey(string subKey)
{
return Registry.LocalMachine.OpenSubKey(subKey);
}
private static string GetRegistryValue(RegistryKey commonKey, string subKey, string keyName)
{
using (commonKey.OpenSubKey(subKey))
{
if (key != null)
{
if (key.GetValue(keyName) != null)
{
return (string)key.GetValue(keyName);
}
}
return null;
}
}
// usage
var commonKey = GetCommonKey("SOFTWARE\\WOW6432Node\\Microsoft");
var version = GetRegistryValue(commonKey, "DataAccess", "Version");
var nodePath = GetRegistryValue(commonKey, "ENROLLMENTS\\ValidNodePaths", "Version");

C# Registry key assignement is null

I'm busy creating a little application for my self and others but I'm kinda stuck here.
I want to get a value of the register 'regedit' with an path. but the value 'RegistryKey' is always null even when I copy the path from the regedit is..
private bool HasKey
{
get
{
try
{
string path = #"Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0002";
using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(path, false))
{
if(key != null)
{
return true;
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
return false;
}
return false;
}
}
I only want to write a bool function that he has found the key.. but the variable 'key' is always null.
Try this
string path = #"\SYSTEM\ControlSet001\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0002";
using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var subKey = key.OpenSubKey(path, false))
{
if (subKey != null)
{
return true;
}
}
}

Loop through registry and get all subkeys and the values in RegistryKey in C#

I need to loop through the registry and get all subkeys and the all values.
This it's what I been trying (to get all subkeys only):
public void OutputRegKey(RegistryKey Key)
{
foreach (string keyname in Key.GetSubKeyNames())
{
try
{
using (RegistryKey key2 = Key.OpenSubKey(keyname))
{
foreach (string valuename in Key.GetValueNames())
{
comboBox1.Items.Add(valuename);
OutputRegKey(key2);
}
}
}
catch
{
}
}
}
How do I get all the values? I need to do two methods: one that gets all the subkeys and other that gets all the values. I'm only asking the one to get all the values. Thank you.
PS: It's not homework or otherwise related to academics. It's something personal.
Once given the RegistryKey, you could easily get the key's ValueNames by Key.GetValueNames() and to get each of the individual key's Value for each ValueName by Key.GetValue(valueName) which will return an object.
Borrowing your code to elaborate, here is how it should be modified to,
private void processValueNames(RegistryKey Key) { //function to process the valueNames for a given key
string[] valuenames = Key.GetValueNames();
if (valuenames == null || valuenames.Length <= 0) //has no values
return;
foreach (string valuename in valuenames) {
object obj = Key.GetValue(valuename);
if (obj != null)
comboBox1.Items.Add(Key.Name + " " + valuename + " " + obj.ToString()); //assuming the output to be in comboBox1 in string type
}
}
public void OutputRegKey(RegistryKey Key) {
try {
string[] subkeynames = Key.GetSubKeyNames(); //means deeper folder
if (subkeynames == null || subkeynames.Length <= 0) { //has no more subkey, process
processValueNames(Key);
return;
}
foreach (string keyname in subkeynames) { //has subkeys, go deeper
using (RegistryKey key2 = Key.OpenSubKey(keyname))
OutputRegKey(key2);
}
processValueNames(Key);
} catch (Exception e) {
//error, do something
}
}

How do I retrieve the default icon for any given file type in Windows?

How do I get the icon that Windows uses by default for a specified file type?
Default icons for a file type irrespective of whether you happen to have one of these types of files handy, are defined in the Window's Registry under
HKEY_CLASSES_ROOT\ type \DefaultIcon(Default)
...but why tinker with that when there is a nice c# code sample here by VirtualBlackFox in his answer to How do I get common file type icons in C#?
Try this
public static Hashtable GetTypeAndIcon()
{
try
{
RegistryKey icoRoot = Registry.ClassesRoot;
string[] keyNames = icoRoot.GetSubKeyNames();
Hashtable iconsInfo = new Hashtable();
foreach (string keyName in keyNames)
{
if (String.IsNullOrEmpty(keyName)) continue;
int indexOfPoint = keyName.IndexOf(".");
if (indexOfPoint != 0) continue;
RegistryKey icoFileType = icoRoot.OpenSubKey(keyName);
if (icoFileType == null) continue;
object defaultValue = icoFileType.GetValue("");
if (defaultValue == null) continue;
string defaultIcon = defaultValue.ToString() + "\\DefaultIcon";
RegistryKey icoFileIcon = icoRoot.OpenSubKey(defaultIcon);
if (icoFileIcon != null)
{
object value = icoFileIcon.GetValue("");
if (value != null)
{
string fileParam = value.ToString().Replace("\"", "");
iconsInfo.Add(keyName, fileParam);
}
icoFileIcon.Close();
}
icoFileType.Close();
}
icoRoot.Close();
return iconsInfo;
}
catch (Exception exc)
{
throw exc;
}
}

Find registry key value and return registry key value path

I have a code which search registry key value in specific key path.
In registry key SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
find all keys with 0000 , 0001 , 0002 , 0003 and so on at the end of registry key. {4D36E972-E325-11CE-BFC1-08002BE10318} . In each key ( for example 0007 ) are subkey called NetCfgInstanceId which holds network interface card ID value , like this {C80949A4-CEDA-4F29-BFE2-059856D7F745} . If finds value, method returns key path !
Problem is an error Cannot convert type 'char' to 'string' in
foreach (string key_value in key.GetValue("NetCfgInstanceId").ToString())
Full code is
public string key_path(RegistryKey root, string root_path, string search_key)
{
string path = string.Empty;
foreach (string keyname in root.GetSubKeyNames())
{
try
{
using (RegistryKey key = root.OpenSubKey(keyname, true))
{
foreach (string key_value in key.GetValue("NetCfgInstanceId").ToString())
{
if (key_value == search_key)
{
string reg_path = (string)key.GetValue("NetCfgInstanceId");
path = reg_path;
}
else
{
path = "Can't find key !";
}
}
}
}
catch (System.Security.SecurityException)
{
//Do nothing !!!
}
}
return path;
}
private void kryptonButton4_Click(object sender, EventArgs e)
{
var answer = key_path(Registry.LocalMachine, #"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}", "{C80949A4-CEDA-4F29-BFE2-059856D7F745}");
MessageBox.Show(answer);
}
How can solve this problem ?
Foreach takes an enumerable value. You are using a string as that value, so the compiler wants a character variable in the foreach. In other words, your call to GetValue(...).ToString() does not return an array of strings, it returns one string. foreach( var x in stringval ), var is a char.
Consider something like this instead ...
var kind = key.GetValueKind("NetCfgInstanceId");
if (kind == RegistryValueKind.MultiString)
{
foreach (var key_value in (string[])key.GetValue("NetCfgInstanceId"))
{
if (key_value == search_key)
{
string reg_path = (string)key.GetValue("NetCfgInstanceId");
path = reg_path;
}
else
{
path = "Can't find key !";
}
}
}
This is assuming you are expecting a multistring in the reg key. You can use the following if it could be a single string ...
if (kind == RegistryValueKind.ExpandString
|| kind == RegistryValueKind.String)
{
var key_value = (string)key.GetValue("NetCfgInstanceId");
if (key_value == search_key)
{
path = key_value;
}
else
{
path = "Can't find key !";
}
}

Categories