I confess I’m new to C#. I am struggling with creating a method to delete a registry key using .NET. The method takes one string parameter which contains the complete key to be removed. Here’s a sample of what I’m trying to do that doesn’t work (obviously):
namespace NameHere
{
class Program
{
static void Main(string[] args)
{
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\")
string strKey=”Test123”;
string fullPath = hklm + "\\" + strKey;
deleteRegKey(fullPath);
}
static void deleteRegKey(string keyName)
{
Registry.LocalMachine.DeleteSubKey(keyName);
}
}
}
I’ve tried a few other iterations and googled for solutions but have, so far, been unable to put the pieces together. Any help would be greatly appreciated. Also, any explanation for why my lame attempt doesn’t work to help clarrify my knowledge gap would be awesome.
This routine should really be a one-liner, like:
Registry.LocalMachine.DeleteSubKey( #"SYSTEM\ControlSet...\etc..." );
You shouldn't need to open a RegistryKey object, because Registry.LocalMachine is kind of already open for you.
If you do need to open a RegistryKey object to do something else, be aware that RegistryKey implements IDisposable, so now that you've created an object, you're responsible for disposing of it no matter what. So, you have to surround your code with try { ... } and call Dispose() in the finally block. Fortunately, this can be coded in C# more elegantly using using:
using( RegistryKey key = Registry.LocalMachine.OpenSubKey(...) ) {
...
}
I believe you have too many \'s. Try this:
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\")
string strKey=”Test123”;
string fullPath = hklm + strKey;
deleteRegKey(fullPath);
I think #Correl has it.
But one way to help you debug would be to use this form of DeleteSubkey:
public void DeleteSubKey(
string subkey,
bool throwOnMissingSubKey
)
instead of the one you call with only one argument, and pass true as the second argument. That way, if
...the specified subkey does not exist, then an exception is raised.
The exception you get would be an ArgumentException.
Related
I'm trying to add the classic "Send with MyApp" in the ContextMenu.
The fact is that my program modifies the windows registry, but it seems that it can't see the update version of it. Indeed, if I start again my program leaving the keys that it modified, it works fine.
How can I solve this (without create another program that modfies the windows registry and then call mine)?
Thank you in advance for the help.
P.s.
Here are the functions that I use to modify the registry
private void AddOption_ContextMenu()
{
RegistryKey _key1 = Registry.ClassesRoot.OpenSubKey("Folder\\shell", true);
RegistryKey _key = Registry.ClassesRoot.OpenSubKey("*\\shell", true);
RegistryKey newkey = _key.CreateSubKey("MyApp");
RegistryKey newkey1 = _key1.CreateSubKey("MyApp");
RegistryKey command = newkey.CreateSubKey("command");
RegistryKey command1 = newkey1.CreateSubKey("command");
string program = Path.GetDirectoryName(Application.ResourceAssembly.Location);
for (int i = 0; i < 3; i++)
program = Path.GetDirectoryName(program);
program = #"""" + program + #"\\MyApp\\bin\\Debug\\MyApp.exe"" ""%1""";
command.SetValue("", program);
command1.SetValue("", program);
newkey.SetValue("", "Send with MyApp");
newkey.SetValue("Icon", Path.GetDirectoryName(Application.ResourceAssembly.Location) + "\\icon.ico");
newkey1.SetValue("", "Send with MyApp");
newkey1.SetValue("Icon", Path.GetDirectoryName(Application.ResourceAssembly.Location) + "\\icon.ico");
command.Close();
command1.Close();
newkey1.Close();
newkey.Close();
_key.Close();
}
public void RemoveOption_ContextMenu()
{
RegistryKey _key = Registry.ClassesRoot.OpenSubKey("*\\shell", true);
RegistryKey _key1 = Registry.ClassesRoot.OpenSubKey("Folder\\shell", true);
_key.DeleteSubKeyTree("MyApp");
_key1.DeleteSubKeyTree("MyApp");
_key1.Close();
_key.Close();
}
Have you tried to read this?
Edited the registry with C# but cannot find the change with regedit
I found this issue years ago and I think that is mandatory to use (at least) two different C# threads to see changes in registry key -->
ref:
C# : How to change windows registry and take effect immediately
I'd like to preface this by highlighting that I am fairly new to C#.
I'm trying to make a program to find and edit a registry value in order to disable CPU core parking using this method: Registry Edit
The issue is that I know the start of the key:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Power\PowerSettings\
But not the Next part but I know the segment after that:
0cc5b647-c1df-4637-891a-dec35c318583
So if it looks like this:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Power\PowerSettings\<UNKNOWN>\0cc5b647-c1df-4637-891a-dec35c318583
How do I find the using Registry and Registrykey? I tried looping through all subkeys and I just get an exception because all I get back is null.
Any suggestions appreciated.
You can use recursion for finding SubKey.
private RegistryKey SearchSubKey(RegistryKey Key,String KeyName)
{
foreach (String subKey in Key.GetSubKeyNames())
{
RegistryKey key1 = Key.OpenSubKey( subKey);
if (subKey.ToUpper() == KeyName.ToUpper())
return key1;
else
{
RegistryKey mReturn = SearchSubKey(key1, KeyName);
if (mReturn != null)
return mReturn;
}
}
return null;
}
Call this function as
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SYSTEM\ControlSet001\Control\Power\PowerSettings\");
RegistryKey SubKey = SearchSubKey(key, "0cc5b647-c1df-4637-891a-dec35c318583");
This function search through all sub keys in main key recursively. If you want to search up to particular level then you have to add that logic in function.
I guess you forgot to mention the Registry key name in a proper fashion. Here is the piece of code which brings out the output :
class Program
{
static void Main(string[] args)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion");
foreach (var v in key.GetSubKeyNames())
{
RegistryKey key1 = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\" + v);
foreach ( var v1 in key1.GetSubKeyNames())
{
if (v1 == "{00EC8ABC-3C5A-40F8-A8CB-E7DCD5ABFA05}")
Console.WriteLine(key1);
}
}
}
}
Please let me know if this works.
When I run the following command, rKey has two values.
RegistryKey sqlServer = Registry.LocalMachine.OpenSubKey( #"SOFTWARE\Microsoft\Microsoft SQL Server", false);
When I run either of the following commands (on the same machine as the same user) I find no values;
RegistryKey sqlServer64 = RegistryKey.OpenBaseKey( RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey sqlServer32 = RegistryKey.OpenBaseKey( RegistryHive.LocalMachine, RegistryView.Registry32 );
Can anyone point me to the answer or a description of the hives vs plain registry access?
Edit:
What I do afterwards is :
StringBuilder sbKeys = new StringBuilder();
foreach (var key in sqlServer.GetValueNames() )
{
sbKeys.AppendLine( key );
}
For all RegistryKeys. For sqlServer I see two Values, for sqlServer32 and SqlServer64 there are no values.
The problem in your second variant is that you have failed to open a sub key. Your sqlServer.GetValueNames() call operates at the root level of a particular hive.
You need it to be like this:
RegistryKey root = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey sqlServer = root.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server");
foreach (var key in sqlServer.GetValueNames())
{ .... }
Done this way it's no different from your first variant (apart from the registry view). I expect that using the appropriate registry view will lead to the solution to your other question.
Naturally you'll want to add some error checking to the code above.
I would to get installed version of an application (say, MyApp) using C#.
I will do this much,
1. Create a 'Set Up' for MyApp of version 5.6
2. Install MyApp.
I will create another application (say VersionTracker)to get the version of installed applications. So if I pass the name 'MyApp' I would like to get the version as '5.6'. If another application say Adobe Reader is installed in my system, I want to get the version of Adobe Reader if I pass 'Adobe Reader'.
I need to know how to build 'VersionTracker'
The first and the most important thing is that not all applications do save their version somewhere in the system. To be honest, only a few of them do that. The place where you should look are the Windows Registry. Most of installed applications put their installation data into the following place:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
However, it's not that easy - on 64bit Windows, the 32bit (x86) applications save their installation data into another key, which is:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
In these keys there are many keys, some of them have got "easy-readable" name, such as Google Chrome, some of them got names such as {63E5CDBF-8214-4F03-84F8-CD3CE48639AD}. You must parse all these keys into your application and start looking for the application names. There are usually in DisplayName value, but it's not always true. The version of the application is usually in DisplayVersion value, but some installers do use another values, such as Inno Setup: Setup Version, ... Some application do have their version written in their name, so it's possible that the application version is already in the DisplayName value.
Note: It's not easy to parse all these registry keys and values and to "pick" the correct values. Not all installers save the application data into these keys, some of them do not save the application version there, etcetera. However, it's usual that the application use these registry keys. [Source: StackOverflow: Detecting installed programs via registry, browsing my own registry]
Alright, so now when you know where you should look, you have to program it all in C#. I won't write the application for you, but I'll tell you what classes you should use and how to. First, you need these:
using System;
using Microsoft.Win32;
To get to your HKEY_LOCAL_MACHINE, create a RegistryKey like this:
RegistryKey baseRegistryKey = Registry.LocalMachine;
Now you need to define subkeys:
string subKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// or "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
Now you need to go to the subkey, so create a new RegistryKey:
RegistryKey uninstallKey = baseRegistryKey.OpenSubKey(subKey);
Now you need to go thru all the subkeys that are there, so first we get the names of all the subkeys:
string[] allApplications = uninstallKey.GetSubKeyNames();
Now you must go thru all the subkeys yourself, one by one, by creating a new registry key (you don't have to, but I'll do it):
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + applicationSubKeyName);
where applicationSubKeyName is the name of the subkey you're currently checking. I recommend foreach statement, which helps you (you must however have some experience with C# already, I'm not going to tell you how to use foreach here).
Now check the application's name and compare it with name of your desired application (you cannot rely on the subkey name, because, as I already said, they can be called for example {63E5CDBF-8214-4F03-84F8-CD3CE48639AD}, so you must check the name here):
string appName = (string)appKey.GetValue("DisplayName");
If it's the correct application (you must check it yourself), find the version:
string appVersion = (string)appKey.GetValue("DisplayVersion");
Et voilà, you have the version. At least there's like a 60 - 80% chance you have...
Remember! If some key or value doesn't exist, the method returns null. Remember to check if the returned value is null everytime, otherwise your application will crash.
Where to find more? The Code Project: Read, write and delete from registry with C#
I really hope I helped you. And if you wanted to know something else and I didn't understand your question, then, please, ask better next time. :)
///
/// Author : Muhammed Rauf K
/// Date : 03/07/2011
/// A Simple console application to create and display registry sub keys
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// it's required for reading/writing into the registry:
using Microsoft.Win32;
namespace InstallationInfoConsole
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Registry Information ver 1.0");
Console.WriteLine("----------------------------");
Console.Write("Input application name to get the version info. (for example 'Nokia PC Suite'): ");
string nameToSearch = Console.ReadLine();
GetVersion(nameToSearch);
Console.WriteLine("----------------------------");
Console.ReadKey();
}
///
/// Author : Muhammed Rauf K
/// Date : 03/07/2011
/// Create registry items
///
static void Create()
{
try
{
Console.WriteLine("Creating registry...");
// Create a subkey named Test9999 under HKEY_CURRENT_USER.
string subKey;
Console.Write("Input registry sub key :");
subKey = Console.ReadLine();
RegistryKey testKey = Registry.CurrentUser.CreateSubKey(subKey);
Console.WriteLine("Created sub key {0}", subKey);
Console.WriteLine();
// Create two subkeys under HKEY_CURRENT_USER\Test9999. The
// keys are disposed when execution exits the using statement.
Console.Write("Input registry sub key 1:");
subKey = Console.ReadLine();
using (RegistryKey testKey1 = testKey.CreateSubKey(subKey))
{
testKey1.SetValue("name", "Justin");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static void GetVersion(string nameToSearch)
{
// Get HKEY_LOCAL_MACHINE
RegistryKey baseRegistryKey = Registry.LocalMachine;
// If 32-bit OS
string subKey
//= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// If 64-bit OS
= "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
RegistryKey unistallKey = baseRegistryKey.OpenSubKey(subKey);
string[] allApplications = unistallKey.GetSubKeyNames();
foreach (string s in allApplications)
{
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + s);
string appName = (string)appKey.GetValue("DisplayName");
if(appName==nameToSearch)
{
string appVersion = (string)appKey.GetValue("DisplayVersion");
Console.WriteLine("Name:{0}, Version{1}", appName, appVersion);
break;
}
}
}
static void ListAll()
{
// Get HKEY_LOCAL_MACHINE
RegistryKey baseRegistryKey = Registry.LocalMachine;
// If 32-bit OS
string subKey
//= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// If 64-bit OS
= "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
RegistryKey unistallKey = baseRegistryKey.OpenSubKey(subKey);
string[] allApplications = unistallKey.GetSubKeyNames();
foreach (string s in allApplications)
{
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + s);
string appName = (string)appKey.GetValue("DisplayName");
string appVersion = (string)appKey.GetValue("DisplayVersion");
Console.WriteLine("Name:{0}, Version{1}", appName, appVersion);
}
}
}
}
Next code base on similar solution is working for me:
var version = GetApplicationVersion("Windows Application Driver");
string GetApplicationVersion(string appName)
{
string displayName;
// search in: CurrentUser
var key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// search in: LocalMachine_32
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// search in: LocalMachine_64
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// NOT FOUND
return null;
}
how can iterate through the registry using C#? I wish to create a structure for representing attributes of each key.
I think what you need is GetSubKeyNames() as in this example.
private void GetSubKeys(RegistryKey SubKey)
{
foreach(string sub in SubKey.GetSubKeyNames())
{
MessageBox.Show(sub);
RegistryKey local = Registry.Users;
local = SubKey.OpenSubKey(sub,true);
GetSubKeys(local); // By recalling itself it makes sure it get all the subkey names
}
}
//This is how we call the recursive function GetSubKeys
RegistryKey OurKey = Registry.Users;
OurKey = OurKey.OpenSubKey(#".DEFAULT\test",true);
GetSubKeys(OurKey);
(NOTE: This was original copied from a tutorial http://www.csharphelp.com/2007/01/registry-ins-and-outs-using-c/, but the site now appears to be down).
private void GetSubKeys(RegistryKey SubKey)
{
foreach(string sub in SubKey.GetSubKeyNames())
{
MessageBox.Show(sub);
RegistryKey local = Registry.Users;
local = SubKey.OpenSubKey(sub,true);
GetSubKeys(local); // By recalling itselfit makes sure it get all the subkey names
}
}
//This is how we call the recursive function GetSubKeys
RegistryKey OurKey = Registry.Users;
OurKey = OurKey.OpenSubKey(#".DEFAULT\test",true);
GetSubKeys(OurKey);
http://www.csharphelp.com/2007/01/registry-ins-and-outs-using-c/
You can use Microsoft.Win32.RegistryKey and the GetSubKeyNames method as described here:
http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey_members%28v=VS.100%29.aspx
Be aware though that this might be very slow if you're iterating through a large part of the registry.
Check out the RegistryKey.GetSubKeyNames method.
This function will retrieve the name of all subkeys and you can iterate through them and do whatever you wish.