I need to retrieve a string from the registry in 32/64 bit windows computers.
I have successfully retrieved info with registry.getvalue in a 64 bit environment, but it returns null in a 32 bit environment.
RegistryKey localKey;
localKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default);
string value = localKey.OpenSubKey(#"Software\MCS").GetValue("path").ToString();
if (value != null)
{
EventLog.WriteEntry("SMS_Service", "Path:" + value);
}
else
{
EventLog.WriteEntry("SMS_Service", "Registry path not found.");
}
Reg query Verification
event viewer
Everything checks out as far as I can tell. I feel like it has to be some kind of permission problem with the registry on the 32 bit machine.
Related
This question already has answers here:
64 bit & 32 bit Registry issue in Windows (Programming in c#)
(2 answers)
Closed 8 years ago.
I'm having hard time with access the registry in my program (C#), here is the details :
My program run on 32 bit & 64 bit OS.
My program will need to get registry keys of software that some has 64 version and some not.
For example:
I'm running a 64 bit OS and i need to read 2 registry keys so i can know the install locations of the 2 different software, one has a 64 bit version so i don't need the "\Wow64node\" and one have only has 32 bit version so i will need the "\Wow64node\"
// 1.MSE: (64 bit version)
string installPath = (string)Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Antimalware", "InstallLocation", null);
if (installPath != null)
{
listViewAV.Items.Add("MSE");
}
// 2.Avast: (32 bit version)
installPath = (string)Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AVAST Software\Avast", "ProgramFolder", null);
if (installPath != null)
{
listViewAV.Items.Add("Avast");
}
Notice that the Avast is in the Wow Node and MSE isnt, but if my program will be running on a 32 bit OS they both be without the Wow Node.
How can i write this code so it works on every scenario?
Scenario 1 : running on a 32 bit machine so all the softwares will be 32 bit as well(no "Wow64node").
Scenario 2 : running on a 64 bit machine so some of the softwares will be 32 bit and some and some 64 bit(need to handle with "Wow64node")
Please write a detailed answer(prefer with a code example).
Thank you
This is essentially the same question as you asked earlier today, and that I answered. I won't repeat my answer. What you are asking for is some code. I can give you that, but I fear that you still don't really understand the registry redirector. I think you are going to have to get on top of that before you can expect to make any progress.
To read a value from the 32 bit view of the registry, for instance Avast, use this code:
RegistryKey rk = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry32);
rk = rk.OpenSubKey(#"SOFTWARE\AVAST Software\Avast");
string installPath = null;
if (rk != null)
{
installPath = rk.GetValue("ProgramFolder", null);
}
if (installPath != null)
{
.... // Avast registry setting found
}
For a program registered in the 64 bit view of the registry, for instance MSE, do it like this:
RegistryKey rk = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry64);
rk = rk.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft Antimalware");
string installPath = null;
if (rk != null)
{
installPath = rk.GetValue("InstallLocation", null);
}
if (installPath != null)
{
.... // Avast registry setting found
}
You don't need to worry about whether or not you are running on a 32 bit or 64 bit system. On a 64 bit system, both views exist, and you get the view that you request. On a 32 bit system, only the 32 bit view exists, and the value of the RegistryView enumeration that you pass is ignored. The documentation says it like this:
If you request a 64-bit view on a 32-bit operating system, the returned keys will be in the 32-bit view.
I'm trying to read a registry key from my application. It is a 32-bit process and is running on a 64-bit system(Win7 64-bit). This is my code:
string value64 = string.Empty;
RegistryKey localKeyRegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
localKey = localKey.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
if (localKey != null)
{
value64 = localKey.GetValue("RegisteredOrganization").ToString();
MessageBox.Show(value64, "value64");
}
On my system the value under this key(SOFTWARE\Microsoft\Windows NT\CurrentVersion) is empty, and the value under this(SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion) is "Microsoft". But the value64 in the message box is empty! Shouldn't it be "Microsoft"?
You are specifying RegistryView.Registry64 so it will be retrieving the value from SOFTWARE\Microsoft\Windows NT\CurrentVersion
If you specify RegistryView.Registry32 it will retrieve it from SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion instead (that is, on a 64-bit system; on a 32-bit system the WOW6432Node doesn't exist so it will just use the normal hive instead).
I think that if you specify RegistryView.Default it will select the hive according to the bitness of the calling process.
I am not able to retrieve a software's Installdir. I have tried GetValue and even OpenSubKey but everytime I get a NULL. I am using VS2008, .Net 3.5, 64bit machine, 32bit process setting.
private string GetInstallPath()
{
string keyValue = string.Empty;
Object key = Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\My Company\\My Tool", "Installdir", null);
...
}
key is returning NULL though there is a valid string there. Equivalent code works in VC++. Please provide your insight to the issue. What am I doing wrong for this supposedly easy task? I cannot use a 'Hive' as it's 4.0 standard. Code level help instead of links would be helpful.
VC++ equivalent
HKEY hkey = NULL;
LSTATUS status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\My Company\\My Tool\\", 0, KEY_READ, &hkey );
if ( status == ERROR_SUCCESS )
{
DWORD type;
char buff[ 100 ];
DWORD numBytes = sizeof( buff );
if ( RegQueryValueExA( hkey, REGISTRY_ENTRY, NULL, &type, (LPBYTE) buff, &numBytes ) == ERROR_SUCCESS )
{
...
}
You mentioned your machine is x64, and your app is 32 bit unless I misread. Given your environment the firs thing I would check is to be sure the key exists in the 64 bit node, HKCU\Software\My Company\... and not in the 32 bit node HKCU\Software\Wow6432Node\My Company\..., if your key exists in the 32 bit node, you will need to make sure your app is a 32 bit app, otherwise, you will need to make sure your app is 64 bit or you won't find the key.
The following code worked for me, running in 64 bit and found the key outside of the Wow6432Node. I don't understand why you can't user 'Hive', it works in both 3.5 and 4.0
RegistryKey regKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\VisualStudio\\10.0");
if (regKey != null)
{
object val = regKey.GetValue("FullScreen");
}
Update:
The following also worked for me, running .NET 3.5, if it's not a platform (x86 vs x64) issue, then it is possibly a permissions problem, make sure that the context under which your app is running has access to the registry key (try running the app as administrator or even system)
object test = Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\VisualStudio\\10.0", "FullScreen", null);
I am using registry keys to access the path of an XML file from installed folder of my machine.
My machine has 32 bit OS. So I am using
using (RegistryKey pRegKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Wow6432Node\Folder\subfolder\key"))
{
if (pRegKey == null)
{
return;
}
else
// get path
But when I run it in 64 bit machine it is showing error, since I have not handled the exception case for 64 bit OS.
How can I handle it??
If your app is 32-bit and you want to install it both on 32-bit and 64-bit OS, use this:
string regPath = string.Format(#"SOFTWARE\{0}AppName\Folder\subfolder\key",
Environment.Is64BitProcess ? #"Wow6432Node\" : string.Empty());
using (RegistryKey pRegKey = Registry.LocalMachine.OpenSubKey(regPath))
{
.....
// Edit:
oh wow. It's odd that I've been working on this for a day now and just realized I needed to do:
key = key.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
And then everything worked. I did not know that you had to do that. Thanks for everyone that responded. I was just messing around and searched for my key and noticed it was being placed in the wrong spot.
// Original question:
I haven't seen a working solution for this and I'm not sure if it's a bug.
I have a C# 32-bit Windows service running on Windows 7 64-bit. My goal is to write to the 64-bit registry and not the Wow6432Node subkey since for AutoAdminLogon a 64-bit system doesn't seem to check the 32-bit view of the keys.
So my code is as follows:
static public void LoginAsGuest(EventLog eventLogger)
{
RegistrySecurity userSecurity = new RegistrySecurity();
RegistryAccessRule userRule = new RegistryAccessRule("Everyone", RegistryRights.FullControl, AccessControlType.Allow);
userSecurity.AddAccessRule(userRule);
var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
key.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", RegistryKeyPermissionCheck.ReadWriteSubTree);
if (key == null)
{
eventLogger.WriteEntry("Error accessing the registry key");
}
else
{
try
{
key.SetValue("AutoAdminLogon", "1", RegistryValueKind.String);
key.SetValue("DefaultUserName", "guest", RegistryValueKind.String);
key.SetValue("DefaultPassword", "password", RegistryValueKind.String);
}
catch (Exception exception)
{
eventLogger.WriteEntry("Problem setting up keys: " + exception);
}
}
key.Close();
Reboot();
}
No exception or error is thrown. Nothing is written to the registry in the 32-bit or 64-bit view. I've tried using:
key.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
But it has the same outcome. Now if I just write without any view then my program successfully writes to the subkey:
SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Winlogon
Basically all I want is to write to the subkey:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Anyone know why the above code isn't writing to the requested key? (I will point out that AutoAdminLogon and the other two keys are used by the windows default credential provider such that when windows starts it checks those keys and if AutoAdminLogon is set to 1 then it logs in automatically with the given username and password. I'm doing this to allow a computer to be logged in as guest by setting the keys then rebooting the computer).
It's odd that I've been working on this for a day now and just realized I needed to do:
key = key.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
And then everything worked. I did not know that you had to do that. Thanks for everyone that responded. I was just messing around and searched for my key and noticed it was being placed in the wrong spot.