How to delete a registry value in C#? - c#

i want to know how can i delete a registry value in C# like "SOFTWARE\Microsoft\Cryptography" and inside Cryptography key i want to delete MachineGuid. i've tried this ("using Microsoft.Win32;")
string keyName = #"Software\Microsoft\Cryptography";
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName, true))
{
if (key == null)
{
MessageBox.Show("Value Cannot Be Found");
}
else
{
key.DeleteValue("MachineGuid");
}
}
But didn't work. (i mean MachineGuid Value was still there)

this should work
string keyName = #"Software\Microsoft\Cryptography";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
{
if (key == null)
{
MessageBox.Show("Value Cannot Be Found");
}
else
{
key.DeleteValue("MachineGuid");
}
}
I dont recommend deleting it though lol

Related

Requested remote registry access is not allowed

Requested registry access is not allowed
I want to access Remote Pc's Registry but it cant allow me to do so.
Below is my code
private static void CheckRemoteRegistry()
{
try {
string serverName = "DESKTOP-2ME3g20M";
NetworkShare share = new
NetworkShare(serverName, "C$", "ARIgTEAM", "02123541");
share.Connect();
String ProductName = string.Empty;
String InstanceName = string.Empty;
RegistryKey key;
RegistryKey key2;
RegistryKey Remotekey =
RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, serverName, RegistryView.Registry64);
if (Remotekey != null)
{
key = Remotekey.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
key2 = Remotekey.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
if (key != null)
{
ProductName = key.GetValue("ProductName").ToString();
InstanceName = key.GetValue("MSSQLSERVER").ToString();
}
}
share.Disconnect();
}
catch(Exception ex) {
throw new Exception(ex.Message);
}
}
key = Remotekey.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
This Is Working
but
key2 = Remotekey.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
this code show's me this error.
If anyone is wondering.
Was able to solve the issue by granting permissions to the following area:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\winreg

installed apps name verus search name

I will be straight forward and say that I found this code online and therefore is not my own. It works perfectly if I type in the name of the program as shown in Programs and Features but for instance, I want to type Mozilla Firefox and have it find the installed Mozilla Firefox 26.0 (x86 en-US). I tried many times to use .substring and .contains in the line that checks the two strings but each time leads the program to just lock up. Any help is appreciated.
Just for side notes:
I am using a list of programs in a txt file that are read in to check against the installed apps.
I ran a messagebox right after it sets the display name and several of the message boxes show up blank. I tried to limit it with string.length not being 0 and length being equal or greater than the string from the txt file but all still locks up the program.
Code:
private static bool IsAppInstalled(string p_machineName, string p_name)
{
string keyName;
// search in: CurrentUser
keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.CurrentUser, keyName, "DisplayName", p_name) == true)
{
return true;
}
// search in: LocalMachine_32
keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
{
return true;
}
// search in: LocalMachine_64
keyName = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
{
return true;
}
return false;
}
private static bool ExistsInRemoteSubKey(string p_machineName, RegistryHive p_hive, string p_subKeyName, string p_attributeName, string p_name)
{
RegistryKey subkey;
string displayName;
using (RegistryKey regHive = RegistryKey.OpenRemoteBaseKey(p_hive, p_machineName))
{
using (RegistryKey regKey = regHive.OpenSubKey(p_subKeyName))
{
if (regKey != null)
{
foreach (string kn in regKey.GetSubKeyNames())
{
using (subkey = regKey.OpenSubKey(kn))
{
displayName = subkey.GetValue(p_attributeName) as string;
MessageBox.Show(displayName);
if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true) // key found!
{
return true;
}
}
}
}
}
}
return false;
}
I have tried too many different things to list (or remember)... If it helps this is the majority of the rest of the code calling it:
private void Button_Click(object sender, EventArgs e)
{
string[] lines = new string[250];
string msg = "";
string path = System.Windows.Forms.Application.StartupPath;
if (blah.Checked)
{
try
{
StreamReader filePick = new StreamReader(#path + "\\blah.txt");
int counter = 0;
while ((lines[counter] = filePick.ReadLine()) != null)
{
counter++;
}
filePick.Close();
}
catch (Exception ex)
{
msg += ex.Message;
}
}
else if (blah2.Checked)
{
try
{
StreamReader filePick = new StreamReader(#path + "\\blah2.txt");
int counter = 0;
while ((lines[counter] = filePick.ReadLine()) != null)
{
counter++;
}
filePick.Close();
}
catch (Exception ex)
{
msg += ex.Message;
}
}
string MACHINE_NAME = System.Environment.MachineName;
int counter2 = 0;
string APPLICATION_NAME = "";
string filename = "";
while (lines[counter2] != null)
{
APPLICATION_NAME = lines[counter2];
try
{
bool isAppInstalled = IsAppInstalled(MACHINE_NAME, APPLICATION_NAME);
if (isAppInstalled == true)
{
appsNeedAttention = true;
msg += APPLICATION_NAME + " is still installed.";
}
counter2++;
}
catch (Exception ex)
{
msg += ex.Message;
}
}
if (blah.Checked == true)
{
filename = "blah.txt";
}
else if (blah2.Checked == true)
{
filename = "blah2.txt";
}
if (counter2 == 0 && File.Exists(filename) == true)
{
msg = "There are no programs listed in the file.";
}
if (msg != "")
{
MessageBox.Show(msg, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
Try to change this part :
if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
To this :
//check null to avoid error
if (!string.IsNullOrEmpty(displayName))
{
//convert both string to lower case to ignore case difference
//and use contains to match partially
if (displayName.ToLower().Contains(p_name.ToLower()))
{
return true;
}
}

Check if application is installed in registry

Right now I use this to list all the applications listed in the registry for 32bit & 64.
I have seen the other examples of how to check if an application is installed without any luck.
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (String a in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(a);
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
registryKey = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (String a in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(a);
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
So this snippet lists it all in the console window and what I am trying to do is
just find one program title out of the list of display names to see if it's installed.
The last thing I tried was
if (subkey.Name.Contains("OpenSSL"))
Console.Writeline("OpenSSL Found");
else
Console.Writeline("OpenSSL Not Found");
Anything I tried came back either false or a false positive. Is there anyone that can show me how to just grab a title out of the list?
Please don't post up the well-known private static void IsApplicationInstalled(p_name) function. It does not work for me at all.
After searching and troubleshooting, I got it to work this way:
public static bool checkInstalled (string c_name)
{
string displayName;
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(c_name))
{
return true;
}
}
key.Close();
}
registryKey = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(c_name))
{
return true;
}
}
key.Close();
}
return false;
}
And I simply just call it using
if(checkInstalled("Application Name"))
This is a clean way to do this without that much code.
private static bool IsSoftwareInstalled(string softwareName)
{
var key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") ??
Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
if (key == null)
return false;
return key.GetSubKeyNames()
.Select(keyName => key.OpenSubKey(keyName))
.Select(subkey => subkey.GetValue("DisplayName") as string)
.Any(displayName => displayName != null && displayName.Contains(softwareName));
}
Call it with a if-statement:
if (IsSoftwareInstalled("OpenSSL"))
I have checked #Stellan Lindell's code and it doesn't work in all cases.
My version should work in all scenarios and checks the specific version of installed programs(x86, x64).
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;
namespace Test
{
internal class Program
{
public enum ProgramVersion
{
x86,
x64
}
private static IEnumerable<string> GetRegisterSubkeys(RegistryKey registryKey)
{
return registryKey.GetSubKeyNames()
.Select(registryKey.OpenSubKey)
.Select(subkey => subkey.GetValue("DisplayName") as string);
}
private static bool CheckNode(RegistryKey registryKey, string applicationName, ProgramVersion? programVersion)
{
return GetRegisterSubkeys(registryKey).Any(displayName => displayName != null
&& displayName.Contains(applicationName)
&& displayName.Contains(programVersion.ToString()));
}
private static bool CheckApplication(string registryKey, string applicationName, ProgramVersion? programVersion)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
if (CheckNode(key, applicationName, programVersion))
return true;
key.Close();
}
return false;
}
public static bool IsSoftwareInstalled(string applicationName, ProgramVersion? programVersion)
{
string[] registryKey = new [] {
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
return registryKey.Any(key => CheckApplication(key, applicationName, programVersion));
}
private static void Main()
{
// Examples
Console.WriteLine("Notepad++: " + IsSoftwareInstalled("Notepad++", null));
Console.WriteLine("Notepad++(x86): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x86));
Console.WriteLine("Notepad++(x64): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x64));
Console.WriteLine("Microsoft Visual C++ 2009: " + IsSoftwareInstalled("Microsoft Visual C++ 2009", null));
Console.WriteLine("Microsoft Visual C-- 2009: " + IsSoftwareInstalled("Microsoft Visual C-- 2009", null));
Console.WriteLine("Microsoft Visual C++ 2013: " + IsSoftwareInstalled("Microsoft Visual C++ 2013", null));
Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x86): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x86));
Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x64): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x64));
Console.ReadKey();
}
}
}
The solution #Hyperion is ok but it has an error because for 32 bit configurations. No 64 bit registers are returned. To receive 64 bit registers, do the following:
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);
Solutions above are really good, but sometimes you have to check if product is installed also on another machine. So there is a version based on solutions above from #Stellan Lindell and #Mroczny Arturek
This method works OK for local machine and also remote machine...
public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
{
string uninstallRegKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));
//Starts from 1, because first one is Default, so we dont need it...
for (int i = 1; i < enumValues.Length; i++)
{
//This one key is all what we need, because RegView will do the rest for us
using (RegistryKey key = (string.IsNullOrWhiteSpace(remoteMachine))
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
: RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
{
if (key != null)
{
if (key.GetSubKeyNames()
.Select(keyName => key.OpenSubKey(keyName))
.Select(subKey => subKey.GetValue("DisplayName") as string)
//SomeTimes we really need the case sensitive/insensitive option...
.Any(displayName => displayName != null && displayName.IndexOf(softwareName, strComparison) >= 0))
{ return true; }
}
}
}
return false;
}
The registry version is only one from two standard options.. Another option is using WMI, but the registry one is much better due to performance, so take WMI only as a alternative.
//This one does't have a case sensitive/insesitive option, but if you need it, just don't use LIKE %softwareName%
//and get all products (SELECT Name FROM Win32_Product). After that just go trough the result and compare...
public static bool IsSoftwareInstalledWMI(string softwareName, string remoteMachine = null)
{
string wmiPath = (!string.IsNullOrEmpty(remoteMachine))
? #"\\" + remoteMachine + #"\root\cimv2"
: #"\\" + Environment.MachineName + #"\root\cimv2";
SelectQuery select = new SelectQuery(string.Format("SELECT * FROM Win32_Product WHERE Name LIKE \"%{0}%\"", softwareName));
if (SelectStringsFromWMI(select, new ManagementScope(wmiPath)).Count > 0) { return true; }
return false;
}
There is my SelectStringsFromWMI method, but you can do this on your own, this is not important part of this solution. But if you are intersted, there it is...
public static List<Dictionary<string, string>> SelectStringsFromWMI(SelectQuery select, ManagementScope wmiScope)
{
List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiScope, select))
{
using (ManagementObjectCollection objectCollection = searcher.Get())
{
foreach (ManagementObject managementObject in objectCollection)
{
//With every new object we add new Dictionary
result.Add(new Dictionary<string, string>());
foreach (PropertyData property in managementObject.Properties)
{
//Always add data to newest Dictionary
result.Last().Add(property.Name, property.Value?.ToString());
}
}
return result;
}
}
}
!!UPDATE!!
Due to really bad performance, there is another improvement. Just get values async..
public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
{
string uninstallRegKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));
//Starts from 1, because first one is Default, so we dont need it...
for (int i = 1; i < enumValues.Length; i++)
{
//This one key is all what we need, because RegView will do the rest for us
using (RegistryKey regKey = (string.IsNullOrWhiteSpace(remoteMachine))
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
: RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
{
if (SearchSubKeysForValue(regKey, "DisplayName", softwareName, strComparison).Result)
{ return true; }
}
}
return false;
}
And the SearchSubKeysForValue method (can be build as extension method):
public static async Task<bool> SearchSubKeysForValue(RegistryKey regKey, string valueName, string searchedValue, StringComparison strComparison = StringComparison.Ordinal)
{
bool result = false;
string[] subKeysNames = regKey.GetSubKeyNames();
List<Task<bool>> tasks = new List<Task<bool>>();
for (int i = 0; i < subKeysNames.Length - 1; i++)
{
//We have to save current value for i, because we cannot use it in async task due to changed values for it during foor loop
string subKeyName = subKeysNames[i];
tasks.Add(Task.Run(() =>
{
string value = regKey.OpenSubKey(subKeyName)?.GetValue(valueName)?.ToString() ?? null;
return (value != null && value.IndexOf(searchedValue, strComparison) >= 0);
}));
}
bool[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
result = results.Contains(true);
return result;
}
I tried the solutions here, but they didnt work in some cases. The reason was, that my programm is 32 bit and runs on 64 bit Windows. With the solutions posted here a 32bit process can not check whether a 64 bit application is installed.
How to access 64 bit registry with a 32 bit process
RegistryKey.OpenBaseKey
I modifed the solutions here to get a working one for this issue:
Usage example
Console.WriteLine(IsSoftwareInstalled("Notepad++"));
Code
public static bool IsSoftwareInstalled(string softwareName)
{
var registryUninstallPath = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
var registryUninstallPathFor32BitOn64Bit = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
if (Is32BitWindows())
return IsSoftwareInstalled(softwareName, RegistryView.Registry32, registryUninstallPath);
var is64BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPath);
var is32BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPathFor32BitOn64Bit);
return is64BitSoftwareInstalled || is32BitSoftwareInstalled;
}
private static bool Is32BitWindows() => Environment.Is64BitOperatingSystem == false;
private static bool IsSoftwareInstalled(string softwareName, RegistryView registryView, string installedProgrammsPath)
{
var uninstallKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView)
.OpenSubKey(installedProgrammsPath);
if (uninstallKey == null)
return false;
return uninstallKey.GetSubKeyNames()
.Select(installedSoftwareString => uninstallKey.OpenSubKey(installedSoftwareString))
.Select(installedSoftwareKey => installedSoftwareKey.GetValue("DisplayName") as string)
.Any(installedSoftwareName => installedSoftwareName != null && installedSoftwareName.Contains(softwareName));
}
Here is my version for 64 bits
public static string[] checkInstalled(string findByName)
{
string[] info = new string[3];
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
//64 bits computer
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
string displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(findByName))
{
info[0] = displayName;
info[1] = subkey.GetValue("InstallLocation").ToString();
info[2] = subkey.GetValue("Version").ToString();
}
}
key.Close();
}
return info;
}
you can call this method like this
string[] JavaVersion = Software.checkInstalled("Java(TM) SE Development Kit");
if the array is empty means no installation found. if it is not empty it will give you the original name, relative path, and location which in most cases that is all we are looking to get.

Is it possible to delete multiple registry entries one after the other?

I am fairly new to c#. I would like to achieve deleting multiple registry entries one after the other but I am getting exception for the first key and after that the code stops deleting other keys.I have tried below mentioned code it works for single key in if block
string[] keyArray = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
foreach (var key in keyArray)
{
try
{
RegistryKey myKey = Registry.ClassesRoot.OpenSubKey(key, true);
if (myKey != null)
{
/*Cisco Secure Desktop*/
myKey.DeleteSubKeyTree("{705EC6D4-B138-4079-A307-EF13E4889A82}");
myKey.DeleteSubKeyTree("{F8FC1530-0608-11DF-2008-0800200C9A66}");
myKey.DeleteSubKeyTree("{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}");
/*Cisco Hostscan*/
myKey.DeleteSubKeyTree("{F8FC1530-0608-11DF-2008-0800200C9A66}");
myKey.DeleteSubKeyTree("{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}");
/*Cisco AnyConnect Secure Mobility Client*/
myKey.DeleteSubKeyTree("{55963676-2F5E-4BAF-AC28-CF26AA587566}");
myKey.DeleteSubKeyTree("{CC679CB8-DC4B-458B-B817-D447B3B6AC31}");
}
else
Console.WriteLine(string.Format("could not open key: {0}", key));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("action {0} failed with\n{1}", key, ex.Message));
}
}
Given to your details you may try the following code
string[] keyArray = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage",
};
foreach (var key in keyArray)
{
try
{
RegistryKey myKey = Registry.ClassesRoot.OpenSubKey(key, true);
if (myKey != null)
myKey.DeleteSubKeyTree("{55963676-2F5E-4BAF-AC28-CF26AA587566}");
else
System.Diagnostics.Debug.WriteLine(string.Format("could not open key: {0}", key));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("action {0} failed with\n{1}", key, ex.Message));
}
}
This should print out some error information, too.
As of your given comment ArgumentException(...) you try to open/delete a subkey {55963676-2F5E-4BAF-AC28-CF26AA587566} that does not exist! Perhaps you should have a look into Registry.OpenSubKey and DeleteSubKeyTree(..)
EDIT: added a new answer as of given details
private static void deleteRegistryKeys2()
{
string[] classIds = {
"{538793D5-659C-4639-A56C-A179AD87ED44}",
/*Cisco Secure Desktop*/
"{705EC6D4-B138-4079-A307-EF13E4889A82}",
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
/*Cisco Hostscan*/
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
"{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}",
/*Cisco AnyConnect Secure Mobility Client*/
"{55963676-2F5E-4BAF-AC28-CF26AA587566}",
"{CC679CB8-DC4B-458B-B817-D447B3B6AC31}"
};
string[] regKeys = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
// iterate every regKey
foreach (var regkey in regKeys)
{
// go for each classId
foreach (var classId in classIds)
{
// get a regKey within a hive, pass classId too
deleteKey(Registry.ClassesRoot.OpenSubKey(regkey, true), classId);
deleteKey(Registry.CurrentUser.OpenSubKey(regkey, true), classId);
deleteKey(Registry.LocalMachine.OpenSubKey(regkey, true), classId);
}
}
Console.WriteLine("Cleanup finished. Press any key to exit");
Console.ReadLine();
}
private static void deleteKey(RegistryKey registryKey, string classId)
{
// check if there is a key
if (registryKey != null)
{
try
{
// try to remove classId within this regKey
registryKey.DeleteSubKeyTree(classId);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Console.WriteLine(
string.Format("could not delete key {0} with classId {1}",
registryKey, classId));
}
}
}
Finally I have better code which is working after lot of effort Please let me know if anyone can do it better
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] clsids = {
"{538793D5-659C-4639-A56C-A179AD87ED44}",
/*Cisco Secure Desktop*/
"{705EC6D4-B138-4079-A307-EF13E4889A82}",
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
/*Cisco Hostscan*/
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
"{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}",
/*Cisco AnyConnect Secure Mobility Client*/
"{55963676-2F5E-4BAF-AC28-CF26AA587566}",
"{CC679CB8-DC4B-458B-B817-D447B3B6AC31}"
};
string[] keys = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
/*Classes root hive*/
for (int i = 0; i<=7; i++ )
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.ClassesRoot.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\"+clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
/*Current user hive*/
for (int i = 0; i <= 7; i++)
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.CurrentUser.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\" + clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
/*Local Machine hive*/
for (int i = 0; i <= 7; i++)
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.LocalMachine.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\" + clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
Console.WriteLine("Cleanup finished. Press any key to exit");
Console.ReadLine();
}
}
}

Copying subcategories in registry

can someone suggest the best way how to copy content of one subcategory in registry to another?
For example we have:
HKEY_CURRENT_USER.Software.MyProgram.ver_1
and running the function check, if there no ver_2, so create ...MyProgram.ver_2 and copy there all content of ...MyProgram.ver_1.
An extension method:
public static void CopyTo(this RegistryKey src, RegistryKey dst)
{
// copy the values
foreach (var name in src.GetValueNames())
{
dst.SetValue(name, src.GetValue(name), src.GetValueKind(name));
}
// copy the subkeys
foreach (var name in src.GetSubKeyNames())
{
using (var srcSubKey = src.OpenSubKey(name, false))
{
var dstSubKey = dst.CreateSubKey(name);
srcSubKey.CopyTo(dstSubKey);
}
}
}
Called like this:
var ver1 = Registry.CurrentUser.OpenSubKey(#"Software\MyProgram\ver_1");
var ver2 = Registry.CurrentUser.OpenSubKey(#"Software\MyProgram\ver_2");
ver1.CopyTo(ver2);
Based on Wallys extension method I implemented an MoveTo extension method.
This code also contains an key.GetParent(...) extension method which will open the parent key (needed because I use DeleteSubKeyTree method to delete the Key after copy succeded.
public static void MoveTo(this RegistryKey src, RegistryKey dst)
{
src.CopyTo(dst);
src.Delete();
}
public static void Delete(this RegistryKey key)
{
using (var parentKey = key.GetParent(true))
{
var keyName = key.Name.Split('\\').Last();
parentKey.DeleteSubKeyTree(keyName);
}
}
public static RegistryKey GetParent(this RegistryKey key)
{
return key.GetParent(false);
}
public static RegistryKey GetParent(this RegistryKey key, bool writable)
{
var items = key.Name.Split('\\');
var hiveName = items.First();
var parentKeyName = String.Join("\\", items.Skip(1).Reverse().Skip(1).Reverse());
var hive = GetHive(hiveName);
using (var baseKey = RegistryKey.OpenBaseKey(hive, key.View))
{
return baseKey.OpenSubKey(parentKeyName, writable);
}
}
private static RegistryHive GetHive(string hiveName)
{
if (hiveName.Equals("HKEY_CLASSES_ROOT", StringComparison.OrdinalIgnoreCase))
return RegistryHive.ClassesRoot;
else if (hiveName.Equals("HKEY_CURRENT_USER", StringComparison.OrdinalIgnoreCase))
return RegistryHive.CurrentUser;
else if (hiveName.Equals("HKEY_LOCAL_MACHINE", StringComparison.OrdinalIgnoreCase))
return RegistryHive.LocalMachine;
else if (hiveName.Equals("HKEY_USERS", StringComparison.OrdinalIgnoreCase))
return RegistryHive.Users;
else if (hiveName.Equals("HKEY_PERFORMANCE_DATA", StringComparison.OrdinalIgnoreCase))
return RegistryHive.PerformanceData;
else if (hiveName.Equals("HKEY_CURRENT_CONFIG", StringComparison.OrdinalIgnoreCase))
return RegistryHive.CurrentConfig;
else if (hiveName.Equals("HKEY_DYN_DATA", StringComparison.OrdinalIgnoreCase))
return RegistryHive.DynData;
else
throw new NotImplementedException(hiveName);
}
This question answer the "how to read/write registry" question, and based on that you can do this:
read "ver_2" key
if "ver_2" doesn't exist, create it
if "ver_2" didn't exist above, read each value in "ver_1" key and write an identical value under "ver_2"
Basically, you read a value, write it, then read another, write it, and so on.

Categories

Resources