C# Winforms get int Value from registry - c#

private void button1_Click(object sender, EventArgs e)
{
int i = (Int32)Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Beerbaum", "TCP_Listening_Delay", null);
MessageBox.Show(i.ToString());
}
In the Registry there is a QWORD-Value(64-Bit) called TCP_Listening_Delay and its value is dec:5000
When I press the button it should open a MessageBox which should display 5000, but it doesn't. All it does is giving me,
"NullReferenceException was unhandled".

Registry.GetValue(String, String, Object) Method
Retrieves the value associated with the specified name, in the
specified registry key. If the name is not found in the specified key,
returns a default value that you provide, or null if the specified key
does not exist.
Returns
null if the subkey specified by keyName does not exist; otherwise, the
value associated with valueName, or defaultValue if valueName is not
found.
However i think your problem is you are probably trying to read 64/32 bit registry hive from a 32/64 bit application
RegistryView Enumeration : On the 64-bit version of Windows, portions
of the registry are stored separately for 32-bit and 64-bit
applications. There is a 32-bit view for 32-bit applications and a
64-bit view for 64-bit applications.
You can specify a registry view when you use the OpenBaseKey and
OpenRemoteBaseKey(RegistryHive, String, RegistryView) methods, and the
FromHandle property on a RegistryKey object.
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var subKey = baseKey.OpenSubKey("blah", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl))
{
if (subKey != null)
{
var value = subKey.GetValue("Somekey");
}
}
}
64 bit Registry Key not updated by 32 bit application

Related

C# Rename Registry value errors "returned null"

So to my final programming project I need to rename a value inside Registry through C#, this is what I wrote so far:
public bool RenameSubKey(string parentKey, string subKeyName, string newSubKeyName)
{
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
RegistryKey rk64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
rk64.OpenSubKey(parentKey);
//copy all the values
foreach (string valueName in rk64.OpenSubKey(subKeyName).GetValueNames())
{
object objValue = rk64.OpenSubKey(subKeyName).GetValue(valueName);
RegistryValueKind valKind = rk64.OpenSubKey(subKeyName).GetValueKind(valueName);
rk64.CreateSubKey(newSubKeyName).SetValue(valueName, objValue, valKind);
}
rk64.DeleteSubKeyTree(subKeyName); // Deletes old value
return true;
}
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(parentKey, false))
{
rk.OpenSubKey(parentKey);
//copy all the values
foreach (string valueName in rk.OpenSubKey(subKeyName).GetValueNames())
{
object objValue = rk.OpenSubKey(subKeyName).GetValue(valueName);
RegistryValueKind valKind = rk.OpenSubKey(subKeyName).GetValueKind(valueName);
rk.CreateSubKey(newSubKeyName).SetValue(valueName, objValue, valKind);
}
rk.DeleteSubKeyTree(subKeyName); // Deletes old value
return true;
}
}
It needs to be able to rename a 32-bit Registry value as well as a 64-bit Registry value (the application is 32-bit). Rename function simply means to create new value with the new name, copy all the data from the old one to the new one and delete the old one.
Let's take an example: There's a ListView presents all the installed application on the PC and I want to change the value UninstallString to !UninstallString with the press of a button so the users won't be able to uninstall the selected application in the ListView. The app might be 64-bit (meaning the Registry values are 64-bit and it requires a little different approach) or it can be 32-bit - Hence comes the if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess).
So in the example I place SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip as my path and I want to rename the value UninstallString to !UninstallString, but it quits on the foreach with an error says System.NullReferenceException: 'Object reference not set to an instance of an object.' Microsoft.Win32.RegistryKey.OpenSubKey(...) returned null.
First of all, let me say, this requieres elevated privileges, the changes are because you want to enter the registry and write in them so you need to actually tell that when you are opening the sub key. Either in 64 or 32 bit. Im not sure about the If, as pointed out before by the general, but this will work at least for 32 bits path
public static bool RenameSubKey(string parentKey, string key, string newValue)
{
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
RegistryKey rk64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(parentKey, RegistryKeyPermissionCheck.ReadWriteSubTree);
rk64.SetValue(key, newValue);
return true;
}
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(parentKey, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
rk.SetValue(key, newValue);
return true;
}
}
Thanks to #nalnpir I fixed the rename Registry value function:
public static bool RenameSubKey(string path, string keyName, string newKeyName)
{
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
RegistryKey rk64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
object objValue = rk64.GetValue(keyName);
RegistryValueKind valKind = rk64.GetValueKind(keyName);
rk64.SetValue(newKeyName, objValue, valKind);
rk64.DeleteValue(keyName);
return true;
}
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
object objValue = rk.GetValue(keyName);
RegistryValueKind valKind = rk.GetValueKind(keyName);
rk.SetValue(newKeyName, objValue, valKind);
rk.DeleteValue(keyName);
return true;
}
}
Now I see that I didn't access it the right way (as he enlightened me) and thus was the error.

How to check other software is installed when installing my software

I want to create a setup to deploy software.My first window of installation is to check master software(other software) is installed in that computer,because i need to add a supporting file to master software's installation folder.
Is that possible in visual studio setup deployment project?
Every software you install, must create entry in Registry.So you can read the particular entry in registry from Visual studio Setup project.
Retrieve a Value from the Registry
how to retrieve the MediaPath value for your computer from the
registry,
The MediaPath value for your computer is located under the following registry subkey:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
You can retrieve this value by using a launch condition. To do this, follow these steps:
In Visual Studio .NET, point to Editor on the View menu, and then
click Launch Conditions.
In the Launch Conditions Editor, click Search Target Machine.
On the Action menu, click Add Registry Search.
By default, Search for RegistryEntry1 is added.
On the View menu, click Properties Window to select the Properties
window for the registry search that you created in previous step.
Change the Name property value to Search for MediaPath.
Change the Property property value to MEDIA_PATH.
When you run the setup project, the MediaPath registry value is retrieved to your
MEDIA_PATH property.
To search HKEY_LOCAL_MACHINE in the registry, click the Root
property, and then click vsdrrHKLM in the drop-down list box for the
property value.
To search the SOFTWARE\Microsoft\Windows\CurrentVersion subkey, type
SOFTWARE\Microsoft\Windows\CurrentVersion in the RegKey property
value text box.
To search for the MediaPath value, type MediaPath in the Value
property value text box.
For More See Hare
Below code is working fine for me
/// <summary>
/// To check software installed or not
/// </summary>
/// <param name="controlPanelDisplayName">Display name of software from control panel</param>
private static bool IsApplictionInstalled(string controlPanelDisplayName)
{
string displayName;
RegistryKey key;
// search in: CurrentUser
key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
if (null != key)
{
foreach (string keyName in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(keyName);
displayName = subkey.GetValue("DisplayName") as string;
if (controlPanelDisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
}
}
// search in: LocalMachine_32
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
if (null != key)
{
foreach (string keyName in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(keyName);
displayName = subkey.GetValue("DisplayName") as string;
if (controlPanelDisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
}
}
// search in: LocalMachine_64
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
if (null != key)
{
foreach (string keyName in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(keyName);
displayName = subkey.GetValue("DisplayName") as string;
if (controlPanelDisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
}
}
// NOT FOUND
return false;
}

OpenSubKey() returns null for a registry key that I can see in regedit.exe

I'm trying to get all the display names of the sub keys within this key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
With this code:
RegistryKey newKey;
string val;
string KeyPath64Bit = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey mainKey = Registry.LocalMachine.OpenSubKey(KeyPath64Bit);
string[] RegKeys64Bits = Registry.LocalMachine.OpenSubKey(KeyPath64Bit).GetSubKeyNames();
foreach (string s in RegKeys64Bits)
{
newKey = mainKey.OpenSubKey(s);
val = newKey.GetValue("DisplayName", -1, RegistryValueOptions.None).ToString();
if (val != "-1")
file64.WriteLine(val);
}
After running the code I can't find one of the keys I need:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}
And it should have the display name: Microsoft Visual C++ 2010 x64 Redistributable - 10.0.30319, but instead the GetSubKeyNames() method gives me the sub key : {DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}.KB2151757 which doesn't have any display name.
Why can't I get the exact sub key I need ({DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}) and how can I get it?
A 32-bit application on a 64-bit OS will be looking at the HKLM\Software\Wow6432Node node by default. To read the 64-bit version of the key, you'll need to specify the RegistryView:
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
using (var key = hklm.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"))
{
// key now points to the 64-bit key
}
The API to do this was added in .NET 4.0; if you're still using 3.5, you'll need to use P/Invoke to access the 64-bit keys:
http://www.rhyous.com/2011/01/24/how-read-the-64-bit-registry-from-a-32-bit-application-or-vice-versa/
In Visual Studio 2017 go to
Project > Properties > Build > Uncheck **Prefer 32-bit** and Platform target as **Any CPU**.

What is the difference in the registry and registry hives

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.

get installed version of an application using c#

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;
}

Categories

Resources