How get the name of an unknown registry key. C# - c#

I'm trying to get the name of a Registry Key and store it as a string.
I know the path that the key will be under.
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\
The key is the Raw path for the recycling bin. The key under this path changes from computer to computer and can store more than one subkey containing the Recycle bin depending on how many users are on the installation. (From my understanding anyway)
My goal is to get the path of the recycling bin automatically so I don't have to dig through the registry to get it. Alternatively you can manually get this path by going to C:\$Recycle.Bin\Recycle Bin and the explorer path bar will then change to the key.
The key in my case appears as S-1-5-21-3905818072-3397350780-xxxxxxxxxx-1001

You can enumerate the sub-keys using GetSubKeyNames https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registrykey.getsubkeynames?view=netframework-4.7.2
using (var key = Registry.LocalMachine(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"))
{
foreach (var subKeyName in key.GetSubKeyNames())
{
}
}

Related

deletesubkeytree not deleting registry folder

I want to delete a folder named EXAMPLE and all values in it in registry that is found under "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\EXAMPLE"
i have tried this ( with true at the end aswell )
Microsoft.Win32.Registry.LocalMachine.DeleteSubKeyTree(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\EXAMPLE");
and tried this
string keyName = #"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
{
key.DeleteSubKeyTree("EXAMPLE", true);
}
They either throw me a null exception or argument exception.
How can i just delete an entire folder with all its keys ?
So that i can have the similar effect from batch :
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\EXAMPLE" /f
The path is incorrect, Registry.LocalMachine doesn't have such a sub key #"HKEY_LOCAL_MACHINE\...". You need to start from "SOFTWARE\..".
string keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
And from your feedback, your program is affected by the Registry Redirector, in which HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node for a 32-bit program, recompile your program from AnyCPU (Prefer 32-bit) to x64 gets rid of the redirection.
The mechanism of Registry Redirector varies on different Windows versions, so I leave this to you for further reading to understand why 64/32 matters in this case.

How can I set this registry value for my User from my installer

The problem from
https://stackoverflow.com/a/37859812/4878558
I need to set Registry value for current user, who launch the install up. Since install going for system mode - I don't know anything about current user
Also my code giving 'System.UnauthorizedAccessException'
SecurityIdentifier sID = WindowsIdentity.GetCurrent().User;
var subKey = Registry.Users.OpenSubKey(sID + "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
subKey.SetValue("test", "test");
enter code here
As Ripple and I have both commented, there's no need for code. Go to the Registry view in the setup project, right-click on Software under HKEY_CURRENT_USER and add the key Microsoft, then Windows, the CurrentVersion, then Run, adding each key.
Then in the Run key view, right-click in the Name, View pane on the right and add new string value, the name being your name. The value, I assume, is the path to your exe, and (assuming it's in the Application folder) make the value [TARGETDIR]my.exe.
If your install is an "Everyone" install then there is a perfectly good reason why it cannot work. This is nothing to do with the code. In an Everyone install that custom action code is running with the System account (NOT the installing user) so you are trying to create a run key for the system account.
Here is how to write autostartup options:
const string AutorunRegistryKey = #"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run";
Registry.SetValue(AutorunRegistryKey, <AppName>, <PathToApplication>);
If you want to remove it from autostartup:
const string AutorunRelativePath = #"Software\Microsoft\Windows\CurrentVersion\Run\";
var key = Registry.CurrentUser.OpenSubKey(AutorunRelativePath, true);
if (key != null)
{
key.DeleteValue(<AppName>, false);
key.Close();
}

Accessing all the keys under classesroot from registry with c#

I have a program which i try is to read all the keys under classesroot but when i do it with GetSubKeyNames() many keys are skipped i only get the key which contains another sub key on it.
RegistryKey key = Registry.ClassesRoot;
foreach (string tempKeyName in key.GetSubKeyNames())
{
MessageBox.Show(tempKeyName);
}
enter image description here
This code shows all the registry keys under HKEY_CLASSES_ROOT. If it doesn't work for you, edit your question telling us Windows version and maybe if you are under a corporate network.
RegistryKey rk = Registry.ClassesRoot;
// Print out the keys.
PrintKeys(rk);
PrintKeys:
static void PrintKeys(RegistryKey rkey)
{
// Retrieve all the subkeys for the specified key.
String[] names = rkey.GetSubKeyNames();
Console.WriteLine("Subkeys of " + rkey.Name);
Console.WriteLine("-----------------------------------------------");
// Print the contents of the array to the console.
foreach (String s in names)
{
Console.WriteLine(s);
}
}
Source:MSDN
JANUARY 2022 - This issue is due to breaking changes introduced in the framework's registry searching library that apparently are not well known
For those searching and still coming up with incorrect registry key results this is due to the 32/64 redirecting in place by Microsoft. This means the old route of iterating for a key in the ClassesRoot hive using Registry.ClassesRoot could unknowingly search the Wow6432 key instead.
The new route is to look it up using the base key while explicitly defining where it should search. Here's the current way to correctly search for a key if you are having this trouble:
RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64)
Note the use of the RegistryKey static member instead of Registry
You can explicitly tell it to look in Registry32, Registry64, or Default - the later of which is what the old process of Registry.ClassesRoot appears to follow.

How to get The Child Folder Name of HKEY_USERS in C#?

Im Trying to get the installed applications in this registry entry.
HKEY_USERS\S-1-5-21-xxxxxx-xxxxxx-xxxxxx-1000\SOFTWARE\Microsoft\Win‌​dows\CurrentVersion\Uninstall
The below code works, if you replace the registry_Key's First part (where the x's are) with your folder name. But how can i get that folder name so that i can use this code on any computer, since that folder name is different on each pc?
In other words, how will i get this part of the string S-1-5-21-xxxxxx-xxxxxx-xxxxxx-1000
registry_key = #"> HKEY_USERS\S-1-5-21-xxxxxx-xxxxxx-xxxxxx-1000\SOFTWARE\Microsoft\Win‌​dows\CurrentVersion\Uninstall";
using (Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
textBox2.Text += subkey.GetValue("DisplayName") + "\r\n";
}
}
}
If you want a list of the USER profiles availabe to traverse the registry on the HKEY_USERS registry hive you could read and filter the contents of
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
However, you need to have permissions to open the registry hive of an user different from the current user (Administrator I think, never done).
If you need only to check the CURRENT_USER registry, it 's easier to use directly the key
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Win‌​dows\CurrentVersion\Uninstall

Writing to registry in a C# application

I'm trying to write to the registry using my C# app.
I'm using the answer given here: Writing values to the registry with C#
However for some reason the key isn't added to the registry.
I'm using the following code:
string Timestamp = DateTime.Now.ToString("dd-MM-yyyy");
string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\"+Application.ProductName+"\\"+Application.ProductVersion;
string valueName = "Trial Period";
Microsoft.Win32.Registry.SetValue(key, valueName, Timestamp, Microsoft.Win32.RegistryValueKind.String);
The Application.name and Application.version 'folders' don't exists yet.
Do I have to create them first?
Also, I'm testing it on a 64b Win version so I think if I want to check the registry for the key added I have to specifically check the 32bit registry in: C:\Windows\SysWOW64\regedit.exe don't I?
First of all if you want to edit key under LocalMachine you must run your application under admin rights (better use CurrentUser it's safer or create the key in installer). You have to open key in edit mode too (OpenSubKey method) to add new subkeys. I've checked the code and it works. Here is the code.
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software",true);
key.CreateSubKey("AppName");
key = key.OpenSubKey("AppName", true);
key.CreateSubKey("AppVersion");
key = key.OpenSubKey("AppVersion", true);
key.SetValue("yourkey", "yourvalue");
You can use the following code to create and open the required registry keys.
RegistryKey SoftwareKey = Registry.LocalMachine.OpenSubKey("Software",true);
RegistryKey AppNameKey = SoftwareKey.CreateSubKey("AppName");
RegistryKey AppVersionKey = AppNameKey.CreateSubKey("AppVersion");
AppVersionKey.SetValue("yourkey", "yourvalue");
You can basically use CreateSubKey for all your application settings, as it will open the key for write access, if it already exists, and create it otherwise. There is no need to create first, and then open. OpenSubKey comes in handy when you are absolutely certain the key already exists, like in this case, with "HKEY_LOCAL_MACHINE\SOFTWARE\"
Also check if your registry calls are getting virtualised. See here for more information.
It can happen if your application is not UAC aware and occurs for compatibility reasons.
Real path
HKEY_LOCAL_MACHINE\Software\FooKey
Virtual path
HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\FooKey
Try to open HKLM\Software first. Then create key for your program, and then create key for version. Howewer, your key could be placed at HKLM\software\WOW6432Node. Check this.
The problem is you don't have enough privileges. Here is a way that works for my:
RegistryKey myKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
myKey = myKey.OpenSubKey(subkey, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
if (myKey != null)
{
myKey.SetValue("DefaultPrinterId", ldiPrinters[e.RowIndex].id, RegistryValueKind.String);
myKey.Close();
}
With RegistryKey.OpenBaseKey you open the correct registry, because when you don't have permissions the registry that you write, it does in another location.
By default, your changes will be written to HKLM\SOFTWARE\WOW6432Node\... because of registry redirection. This can be quite confusing.
In order to write to HKLM\SOFTWARE\..., you need to use RegistryKey.OpenBaseKey to open the 64-bit registry:
var path = #"SOFTWARE\...";
var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var key = baseKey.CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
key.SetValue(name, value, RegistryValueKind.String);
Also, you need to have permission to write to the specified registry key.
You can get permission either by assigning permissions to specific users or service accounts or by running your app in elevated mode.

Categories

Resources