I'm trying to read the registry key "RPSessionInterval" from the subkey "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" in C#. I'm using the following code and getting the exception "Object reference not set to an instance of an object."
string systemRestore = #"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore";
RegistryKey baseRegistryKey = Registry.LocalMachine;
public string SystemRestoreStatus(string subKey, string keyName)
{
RegistryKey rkSubKey = baseRegistryKey.OpenSubKey(systemRestore);
if (rkSubKey != null)
{
try
{
string sysRestore = rkSubKey.GetValue("RPSessionInterval").ToString();
if (string.Compare(sysRestore, "1") == 0)
{
MessageBox.Show("System Restore is Enabled!");
return "System Restore is Enabled!";
}
else if (string.Compare(sysRestore, "0") == 0)
{
MessageBox.Show("System Restore is Disabled!");
return "System Restore is Disabled!";
}
else
{
return null;
}
}
catch (Exception ex) //This exception is thrown
{
MessageBox.Show("Error while reading registry key: " + subKey + "\\" + keyName + ". ErrorMessage: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
else
{
MessageBox.Show("Error while reading registry key: " + subKey + "\\" + keyName + " does not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
Here is a picture showing that the registry key actually exists:
You most likely have a spelling issue for the call to SystemRestoreStatus, which is causing the exception on the following line:
string sysRestore = rkSubKey.GetValue(keyName).ToString();
If you aren't sure whether the value will exist or not, you can change this line to:
string sysRestore = rkSubKey.GetValue(keyName) as string;
and then test to see if the string is null or empty before trying to use it.
Update
Another possibility is that you are executing the code from a 32-bit application on a 64-bit OS. In this case, .Net helpfully redirects your request to the
SOFTWARE\Wow6432Node\Microsoft\...
node instead.
You can get around this issue by using RegistryKey.OpenBaseKey using RegistryView.Registry64 as the second parameter.
You probably have the wrong bitness for your C# application. By default, a Visual Studio 2010 C# project will compile to x86 (32-bit). A 32-bit application running on a 64-bit OS can generally only access the 32-bit registry, the contents of which are often different than the native 64-bit registry. Change the architecture to "Any CPU" or "x64" and it may work.
Related
We're developing a Click-Once WPF Windows Application that retrieves all its data from a database. I implemented a Form where a User could enter the corresponding data and using a SqlConnectionStringBuilder we build the Connection String and that works just fine.
We then add the Connection String to the ConfigurationManager using
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
If we use some other ConfigurationUserLevel, the application crashes (I don't know why yet, but I believe the Entity Framework Model tries to load the connection string and doesn't find it, because the file is not stored in the correct User Level?). Now, we store the connection string in a separate file and load it in App.config so we don't have to check it into Version Control:
<connectionStrings configSource="connections.config"/>
We don't deploy this file because it contains our own development connection strings. Rather, we create an empty file for deployment where the user-entered connection string will be stored. This works completely fine.
Our problem is that with a click-once update, the file will be "lost". What is the best way to store persistent per-user connection strings encrypted in a configuration file? Or should we completely switch to Registry? Or create our own encrypted File somewhere outside the %APPDATA%/Local/Apps/2.0/...../ folders and load it manually when initializing the Entity Framework Context?
You can go to MSDN site it might help you
https://msdn.microsoft.com/en-us/library/dd997001.aspx
with the help of below code, you need to modify this code for your requirement, hope this will help.
To create a custom ClickOnce application installer
In your ClickOnce application, add references to System.Deployment and System.Windows.Forms.
Add a new class to your application and specify any name. This walkthrough uses the name MyInstaller.
Add the following Imports or using statements to the top of your new class.
using System.Deployment.Application;
using System.Windows.Forms;
Add the following methods to your class.
These methods call InPlaceHostingManager methods to download the deployment manifest, assert appropriate permissions, ask the user for permission to install, and then download and install the application into the ClickOnce cache. A custom installer can specify that a ClickOnce application is pre-trusted, or can defer the trust decision to the AssertApplicationRequirements method call. This code pre-trusts the application
Note:- Permissions assigned by pre-trusting cannot exceed the permissions of the custom installer code.
InPlaceHostingManager iphm = null;
public void InstallApplication(string deployManifestUriStr)
{
try
{
Uri deploymentUri = new Uri(deployManifestUriStr);
iphm = new InPlaceHostingManager(deploymentUri, false);
}
catch (UriFormatException uriEx)
{
MessageBox.Show("Cannot install the application: " +
"The deployment manifest URL supplied is not a valid URL. " +
"Error: " + uriEx.Message);
return;
}
catch (PlatformNotSupportedException platformEx)
{
MessageBox.Show("Cannot install the application: " +
"This program requires Windows XP or higher. " +
"Error: " + platformEx.Message);
return;
}
catch (ArgumentException argumentEx)
{
MessageBox.Show("Cannot install the application: " +
"The deployment manifest URL supplied is not a valid URL. " +
"Error: " + argumentEx.Message);
return;
}
iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted);
iphm.GetManifestAsync();
}
void iphm_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)
{
// Check for an error.
if (e.Error != null)
{
// Cancel download and install.
MessageBox.Show("Could not download manifest. Error: " + e.Error.Message);
return;
}
// bool isFullTrust = CheckForFullTrust(e.ApplicationManifest);
// Verify this application can be installed.
try
{
// the true parameter allows InPlaceHostingManager
// to grant the permissions requested in the applicaiton manifest.
iphm.AssertApplicationRequirements(true) ;
}
catch (Exception ex)
{
MessageBox.Show("An error occurred while verifying the application. " +
"Error: " + ex.Message);
return;
}
// Use the information from GetManifestCompleted() to confirm
// that the user wants to proceed.
string appInfo = "Application Name: " + e.ProductName;
appInfo += "\nVersion: " + e.Version;
appInfo += "\nSupport/Help Requests: " + (e.SupportUri != null ?
e.SupportUri.ToString() : "N/A");
appInfo += "\n\nConfirmed that this application can run with its requested permissions.";
// if (isFullTrust)
// appInfo += "\n\nThis application requires full trust in order to run.";
appInfo += "\n\nProceed with installation?";
DialogResult dr = MessageBox.Show(appInfo, "Confirm Application Install",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (dr != System.Windows.Forms.DialogResult.OK)
{
return;
}
// Download the deployment manifest.
iphm.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(iphm_DownloadProgressChanged);
iphm.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>(iphm_DownloadApplicationCompleted);
try
{
// Usually this shouldn't throw an exception unless AssertApplicationRequirements() failed,
// or you did not call that method before calling this one.
iphm.DownloadApplicationAsync();
}
catch (Exception downloadEx)
{
MessageBox.Show("Cannot initiate download of application. Error: " +
downloadEx.Message);
return;
}
}
/*
private bool CheckForFullTrust(XmlReader appManifest)
{
if (appManifest == null)
{
throw (new ArgumentNullException("appManifest cannot be null."));
}
XAttribute xaUnrestricted =
XDocument.Load(appManifest)
.Element("{urn:schemas-microsoft-com:asm.v1}assembly")
.Element("{urn:schemas-microsoft-com:asm.v2}trustInfo")
.Element("{urn:schemas-microsoft-com:asm.v2}security")
.Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum")
.Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet")
.Attribute("Unrestricted"); // Attributes never have a namespace
if (xaUnrestricted != null)
if (xaUnrestricted.Value == "true")
return true;
return false;
}
*/
void iphm_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)
{
// Check for an error.
if (e.Error != null)
{
// Cancel download and install.
MessageBox.Show("Could not download and install application. Error: " + e.Error.Message);
return;
}
// Inform the user that their application is ready for use.
MessageBox.Show("Application installed! You may now run it from the Start menu.");
}
void iphm_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// you can show percentage of task completed using e.ProgressPercentage
}
To attempt installation from your code, call the InstallApplication method. For example, if you named your class MyInstaller, you might call InstallApplication in the following way.
MyInstaller installer = new MyInstaller();
installer.InstallApplication(#"\\myServer\myShare\myApp.application");
MessageBox.Show("Installer object created.");
I am trying to access a registry key in LocalMachine. The code works on my machine, but does not work on my friend's. I have looked at his registry and the key is in the same place as mine.
I tried to put try{} catch{} blocks around OpenBaseKey to see if I can see which exception is being thrown, and none of the exceptions are being caught (Makes me think that it doesn't get past OpenBaseKey.
So, what is happening on my friend's machine, the application will run until my MessageBox.Show("Getting Registry Key") and then crash. I have included a screen shot of the error box.
What could be causing this?
string path = string.Empty;
const string hfss_key_name = #"SOFTWARE\Ansoft\HFSS\2014.0\Desktop";
const string hfss_value = "LibraryDirectory";
MessageBox.Show("Getting Registry Key");
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
localKey = localKey.OpenSubKey(hfss_key_name);
if(localKey != null)
{
path = localKey.GetValue(hfss_value).ToString();
path += #"\HFSS\userlib\";
}
Error Window:
I found the issue, I had the wrong hfss_value. For some reason his and my value are different for that LibraryDirectory. Thanks for all the help.
As it has been pointed out you need to catch the exception to determine why there is a problem. Otherwise, your application can crash exactly as you experience it.
But even without any details about the exception with some code inspection it is perhaps possible to reveal the source of the exception.
Unless you have some weird security settings reading from the registry should be possible and you are careful to check for existence of the key. However, the call to GetValue will return null if the value is missing and calling ToString on null will throw a NullReferenceException. The next line of code should not throw an exception even if path is null.
So changing this code
path = localKey.GetValue(hfss_value).ToString();
path += #"\HFSS\userlib\";
into this code
var value = localKey.GetValue(hffs_value);
if (value != null)
path = value + #"\HFSS\userlib\";
should fix the problem if I am not mistaken.
You probably don't have permissions to get to the key; it is crashing because you're not catching exception thrown.
Change your code to catch the exception and it should help you figure it out:
string path = string.Empty;
const string hfss_key_name = #"SOFTWARE\Ansoft\HFSS\2014.0\Desktop";
const string hfss_value = "LibraryDirectory";
MessageBox.Show("Getting Registry Key");
try
{
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
localKey = localKey.OpenSubKey(hfss_key_name);
if (localKey != null)
{
path = localKey.GetValue(hfss_value).ToString();
path += #"\HFSS\userlib\";
}
}
catch (SecurityException secex)
{
MessageBox.Show("SecurityException: " + secex);
}
catch (UnauthorizedAccessException uex)
{
MessageBox.Show("UnauthorizedAccessException: " + uex);
}
catch (Exception ex)
{
MessageBox.Show("Exception: " + ex);
}
Make sure you are administrator on your friends machine. LocalMachine generally needs admin privileges. you might check out http://msdn.microsoft.com/en-us/library/windows/desktop/ms724878(v=vs.85).aspx
If you run your app with administrator privileges (right mouse button -> Run as administrator) and it works, it's a permission problem.
If it still crashes, most likely it's because you have a 64 bit Windows, while he has a 32 bit Windows or vice versa.
I will check my Windows os name (Windows 8 Pro) in c# but it gives an error, what's wrong?
RegistryKey reg = Registry.LocalMachine.OpenSubKey(#"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", true);
string currentKey;
currentKey = reg.GetValue("ProductName", true).ToString();
textBox1.Text = currentKey;
You can use Environment.OSVersion for this.
Edit:
Getting the OS name is answered here: Stackoverflow OS Friendly name
I'll just quote MSDN:
Registry.GetValue()-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 a null reference (Nothing in Visual Basic) if the specified key does not exist.
This means that the value you are trying to get is not available.
Edit possible Solution:
Source: How to get the “friendly” OS Version Name?
private string GetOSName()
{
var name = (from x in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>()
select x.GetPropertyValue("Caption")).First();
return name != null ? name.ToString() : "Unknown";
}
And to check whether OS is 32 or 64bit use following code:
private string GetOSBitness()
{
if (Environment.Is64BitOperatingSystem == true)
return " x64";
else
return " x86";
}
Above code will return (at least on my system):
Microsoft Windows 7 Professional x64
You can get the commercial name of your operating system, including service pack information by querying the Windows Management Instrumentation interface:
public static string GetOSNameAndVersion()
{
string str = Environment.OSVersion.ToString();
try
{
var obj2 = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
.Get()
.Cast<System.Management.ManagementObject>()
.First<System.Management.ManagementObject>();
str = ((string)obj2["Caption"]).Trim();
string spMaj = obj2["ServicePackMajorVersion"].ToString();
string spMin = obj2["ServicePackMinorVersion"].ToString();
string osVer = obj2["Version"].ToString();
if (((spMaj != "") && (spMaj != "0")) || ((spMin != "") && (spMin != "0")))
{
str = str + " SP " + spMaj;
if ((spMin != "") && (spMin != "0"))
{
str = str + "." + spMin;
}
}
if (Environment.Is64BitOperatingSystem)
{
str = str + " x64";
}
else
{
str = str + " x86";
}
str = str + " (" + osVer + ")";
}
catch
{
// TODO: Implement your own exception handling here
// the way it is, the method will fall back on to the Environment.OSVersion
// if the query fails
}
if (str.StartsWith("Microsoft"))
{
str = str.Substring("Microsoft".Length + 1);
}
return str;
}
Hacking at the registry is probably the wrong solution.
But why is it failing? Since you use Registry.LocalMachine, the HKLM is wrong. Remove the HKLM. That's a clear error.
On top of that watch out for registry redirection. Perhaps your process is 32 bit but the value you are looking for is in the 64 bit view of the registry. Use the RegistryView enumeration to gain access to the 64 bit view.
Your program is subject to what I presume to be a NullReferenceException because the program cannot find the registry sub-key because the path that you have supplied is incorrect.
You do not need to specify the hive in the hive path because your relative path is already the local hive. Exclude the hive from the path like like this:
Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Microsoft\Windows NT\CurrentVersion", true);
Depending on your programs' access privileges and operating system configuration your program may still throw an exception due to your program having insufficient access permissions.
Not quite sure why I can't get this file to delete. I'm logged in as Admin, tried "Run as Admin", tried running in the same folder, tried setting permissions on the file, tried creating a test 1.txt file to delete and no luck. It is acting like the file isn't there. I can see it in Windows Explorer. Please any help is welcome. Thank you for your time.
public void deleteFile(string FileToDelete)
{
//sets system32 to system32 path
string system32 = Environment.SystemDirectory + #"\";
//File.SetAttributes(#system32 + FileToDelete, FileAttributes.Normal);
try
{
//check if file exists
if (!File.Exists(#system32 + #FileToDelete))
{
//if it doesn't no need to delete it
Console.WriteLine("File doesn't exist or is has already been deleted.");
//Console.WriteLine(system32 + FileToDelete);
} //end if
//if it does, then delete
else
{
File.Delete(system32 + FileToDelete);
Console.WriteLine(FileToDelete + " has been deleted.");
} //end else
} //end try
//catch any exceptions
catch (Exception ex)
{
Console.WriteLine(Convert.ToString(ex));
} //end catch
} //end DeleteFile
I created a test file "test.txt" and it worked no problem. I should not that I didn't use the method you posted, but rather used the contents of your supplied method and used them within the main() method of a console application.
ou should also add ReadLine() to display any messages that are returned.
This is what I used, not that it's much different from what you supplied. If this code doesn't work for you then it must be a system privileged issue.
static void Main(string[] args)
{
string FileToDelete = "test.txt";
//sets system32 to system32 path
string system32 = Environment.SystemDirectory + #"\";
try
{
//check if file exists
if (!File.Exists(system32 + FileToDelete))
{
//if it doesn't no need to delete it
Console.WriteLine("File doesn't exist or is has already been deleted.");
//Console.WriteLine(system32 + FileToDelete);
Console.ReadLine();
} //end if
//if it does, then delete
else
{
File.Delete(system32 + FileToDelete);
Console.WriteLine(FileToDelete + " has been deleted.");
Console.ReadLine();
} //end else
} //end try
//catch any exceptions
catch (Exception ex)
{
Console.WriteLine(Convert.ToString(ex));
Console.ReadLine();
} //end catch
}
Try this one out
check if file exist on 64 bits system using File.Exists
If you're using Vista / Windows 7, maybe you're running into file virtualization issues. Have you tried adding a manifest with a <requestedExecutionLevel level="requireAdministrator"/> line in it ?
I need to get a list of installed program on local machine with application icons. Below is the code snippet that am using to get the list of installed program and installed directory path.
/// <summary>
/// Gets a list of installed software and, if known, the software's install path.
/// </summary>
/// <returns></returns>
private string Getinstalledsoftware()
{
//Declare the string to hold the list:
string Software = null;
//The registry key:
string SoftwareKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(SoftwareKey))
{
//Let's go through the registry keys and get the info we need:
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
//If the key has value, continue, if not, skip it:
if (!(sk.GetValue("DisplayName") == null))
{
//Is the install location known?
if (sk.GetValue("InstallLocation") == null)
Software += sk.GetValue("DisplayName") + " - Install path not known\n"; //Nope, not here.
else
Software += sk.GetValue("DisplayName") + " - " + sk.GetValue("InstallLocation") + "\n"; //Yes, here it is...
}
}
catch (Exception ex)
{
//No, that exception is not getting away... :P
}
}
}
}
return Software;
}
Now the issue is how i can get the installed application icon ?
Thanks in advance.
To determine if its an update, there will be a key called IsMinorUpgrade. This is present and set to a 1 for updates. If it's 0 or not present, then it's not an update.
To get an icon from an executable, use this code:
VB:
Public Function IconFromFilePath(filePath As String) As Icon
Dim result As Icon = Nothing
Try
result = Icon.ExtractAssociatedIcon(filePath)
Catch ''# swallow and return nothing. You could supply a default Icon here as well
End Try
Return result
End Function
C#:
public Icon IconFromFilePath(string filePath)
{
Icon result = null;
try {
result = Icon.ExtractAssociatedIcon(filePath);
} catch { }
return result;
}
To extract icon of installed windows application first we need to figure out the location of icon for the installed windows application. This information is stored in registry at following locations -
Key name - HEKY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Value - DisplayIcon
Key name - HKEY_CLASSES_ROOT\Installer\Products{productID}
Value - ProductIcon
For more detail and code to get application icons -
http://newapputil.blogspot.in/2015/06/extract-icons-of-installed-windows_17.html