Registry key null on 64 bit machine - c#

This seemed quite a simple task. First I write registry key
string strHiveName = #"Software\AAAA";
RegistryKey key1_LM;
key1_LM = Registry.LocalMachine.CreateSubKey(strHiveName);
key1_LM.SetValue("Val1", strHiveName);
key1_LM.Close();
and I find it here
HKEY_USERS\S-1-5-21-2753797750-1692135373-930909737-45181\Software\AAAA
when I want to read it with:
RegistryKey root_LM32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
RegistryKey foundProgramKey_LM32 = root_LM32.OpenSubKey(#"SOFTWARE\AAAA");
RegistryKey root_LM64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey foundProgramKey_LM64 = root_LM64.OpenSubKey(#"SOFTWARE\AAAA");
this since I want to make it run on both 32 and 64 bit machines so I expect that at least of the two registry keys are not null but that's not the case.
I have searched this and this but none seems to help.

Related

Why is the Registry Key showing null in C# even if it is present in Registry Editor?

Here is my c# code:
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile", true))
{
key.CreateSubKey("NetworkThrottlingIndex");
key.SetValue("NetworkThrottlingIndex", "0000000a", RegistryValueKind.DWord);
key.CreateSubKey("SystemResponsiveness");
key.SetValue("SystemResponsiveness", "00000000", RegistryValueKind.DWord);
key.CreateSubKey("NoLazyMode");
key.SetValue("NoLazyMode", "1");
}
So what is happening here is that I am getting an error
System.NullReferenceException
on the line
key.CreateSubKey("NetworkThrottlingIndex");
because the key is null.
I checked several times but this key is present in my registry editor.
Any idea about what is wrong here?
The SOFTWARE registry key is redirected depending on the bitness of your application and Windows.
To access your key via a x86/32bit EXE (on 64 bit Windows) request the 64 bit Registry View:
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
using (var key = hklm.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
...
}
Also note that NetworkThrottlingIndex is a sub-key (i.e. a "Folder") and thus you cannot set its value as it has none. Additionally you would use hex literals for the DWORD values (0x0000000a) rather that strings.

C# writing to Registry key in HKCU doesn't work

I am attempting to create a key in the HKCU\SOFTWARE\Classes\CLSID using the following code:
var softwareKey = Registry.CurrentUser;
var key = softwareKey?.OpenSubKey("SOFTWARE\\Classes\\CLSID", true);
key = key?.CreateSubKey("{220176f5-8cff-4e42-b20c-c2d6b32b133c}", RegistryKeyPermissionCheck.ReadWriteSubTree);
key?.SetValue("", "test value");
It doesn't add the entry, it doesn't raise an error and nothing whatsoever appears in ProcessMonitor.
This is true running visual studio as Administrator, but also running as a regular user.
Any ideas?
Courtesy of AlexK, the answer to this was that the entry was being written due to 64 bit registry redirection - the entries were being written to HKEY_CURRENT_USER\SOFTWARE\Classes\WOW6432Node\CLSID.
And I have found the solution to target the standard node on a 64-bit windows installation is to use RegistryKey.OpenBaseKey as follows:
var softwareKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
You can refer below example :-
RegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Classes\WOW6432Node\CLSID\", True)
RegKey.CreateSubKey("{00000000-EAF8-3196-9360-1AADDCDABE1B}")
RegKey.Close()
Reference link :-
https://www.codeproject.com/Questions/273588/How-to-create-a-guid-key-under-HKEY-CLASSES-ROOT-C
Edit 1:
Another example :-
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Names");
key.SetValue("Name", "Isabella");
key.Close();

Using OpenSubKey not finding node that exists

I am using the cookie cutter code to get a registry key object in C#:
RegistryKey reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\\MyNewKeyName\\");
After I run this code reg = null. However, if I switch the value passed to OpenSubKey to be any value in the registry under SOFTWARE that has additional nodes below it reg will now have a value. I've tried multiple keys with this pattern and it works. If I put any any key name that does not have additional child nodes it does not work. Ultimately I'm trying to read a string value inside of MyNewKeyName.
Why does my code not work and reg get populated if my key does not have any additional nodes below it?
Well it turns out that the values in the '32-bit' registry and the '64-bit' registry are not identical. So when viewing the registry via 'regedit' and seeing everything, programatically you may not and that's the issue I was running into. I noticed this by running GetSubKeyNames() and inspecting the keys returned. The quick answer is to check both versions of the registry to find the value sought:
//Check the 64-bit registry for "HKEY_LOCAL_MACHINE\SOFTWARE" 1st:
RegistryKey localMachineRegistry64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey reg64 = localMachineRegistry64.OpenSubKey(registryKeyLocation, false);
if (reg64 != null)
{
return reg64.GetValue(registryKeyName, true).ToString();
}
//Check the 32-bit registry for "HKEY_LOCAL_MACHINE\SOFTWARE" if not found in the 64-bit registry:
RegistryKey localMachineRegistry32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey reg32 = localMachineRegistry32.OpenSubKey(registryKeyLocation, false);
if (reg32 != null)
{
return reg32.GetValue(registryKeyName, true).ToString();
}
I think the problem is you are compiling it as x86 instead of compiling it as an x64 application. Follow the below steps:
Right click on Project
Select Properties
Select the Build tab
Change "Platform Target" to "x64"
Now run the project.

C# Cant Access Some Registry Values

I need to read default value of HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID{CF2CF428-325B-48d3-8CA8-7633E36E5A32}\InprocServer32
In my Project options "Prefer 32-Bit" is unchecked and Platform target is Any CPU, i'm running on Windows-7 64 Bit operating system.
I tried everything and read A LOT of topics about this issue but i can't still read this value.
Please, can you write the actual code ?
I Tried,
RegistryKey LocalMachine32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey location = LocalMachine32.OpenSubKey(#"Software\Wow6432Node\Classes\CLSID\{CF2CF428-325B-48d3-8CA8-7633E36E5A32}\InprocServer32", true);
String myValue = location.GetValue("").ToString();
.
RegistryKey LocalMachine64 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey location = LocalMachine64.OpenSubKey(#"Software\Wow6432Node\Classes\CLSID\{CF2CF428-325B-48d3-8CA8-7633E36E5A32}\InprocServer32", true);
String myValue = location.GetValue("").ToString();
.
RegistryKey LocalMachine64 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey location = LocalMachine64.OpenSubKey(#"Software\Classes\CLSID\{CF2CF428-325B-48d3-8CA8-7633E36E5A32}\InprocServer32", true);
String myValue = location.GetValue("").ToString();
.
RegistryKey LocalMachine32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey location = LocalMachine32.OpenSubKey(#"Software\Classes\CLSID\{CF2CF428-325B-48d3-8CA8-7633E36E5A32}\InprocServer32", true);
String myValue = location.GetValue("").ToString();
But no luck :(
As far as I'm aware you cannot do this with .NET Framework calls; in the past I've used P/Invoke calls to advapi32.dll's RegOpenKeyEx, RegQueryValueEx, and RegQueryValueEx methods to read from a specific bitness registry.
Here is an article with an example of doing this:
http://blogs.msdn.com/b/cumgranosalis/archive/2005/12/19/win64registrypart2.aspx
Edit:
The reason it doesn't work in Windows 7 (along with other potentially helpful resources) is discussed here:
How to open a WOW64 registry key from a 64-bit .NET application

SetValue 64bit machine registry

I want to set a value for 'NoModify' in below registry path.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XXXX"
I am using below code and it works only for X86 machines. Can you see any reason why this is not working for x64 machines?
// This value is correct
RegistryView registryView = releaseFlags.Contains("PLATFORM_X86") ? RegistryView.Registry64 : RegistryView.Registry32;
using (RegistryKey hkeyLocalMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey noModifyKey = hkeyLocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{xxxx}", true); //SL: Key Name
if (noModifyKey != null)
{
noModifyKey.SetValue("NoModify", 0);
noModifyKey.Flush();
}
}
When you are on a 64 bit machine and your app is 32 bit - it should store these settings in the HKLM\Software\WOW6432Node instead of the HKLM\Software\ node.
You should open base key in this way.
It works for me.
var rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
if (Environment.Is64BitOperatingSystem) {
rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
var val = rk.OpenSubKey("SOFTWARE\\Pourab\\sanjande", true);
val.SetValue("test", "testvalue");
}
As far as you compiles your .NET program as x86 not AnyCPU, you will be using the "correct" registry keys meant for x86 in any circumstances because it will be running as x86.
If you compile it as x64 or AnyCPU, it could be quite tricky because it will probably run as x64 on an x64 machine and uses the "wrong" registry where HKLM\SOFTWARE for x86 programs is actually HKLM\SOFTWARE\WOW6432Node.
It's my mistake in the code.
RegistryView registryView = releaseFlags.Contains("PLATFORM_X86") ? RegistryView.Registry64 : RegistryView.Registry32;
Should be as follows:
RegistryView registryView = releaseFlags.Contains("PLATFORM_X86") ? RegistryView.Registry32 : RegistryView.Registry64;

Categories

Resources