No error, no exception, no nothing. Everything seems to be OK, except that the registry remain as it is.
class Program
{
static void Main(string[] args)
{
try
{
Edit();
}
catch (Exception)
{
Restore(); // not included in the sample for simplicity
}
}
public static void Edit()
{
Microsoft.Win32.RegistryKey Login;
Login = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ConfigurationManager.AppSettings["Login"].ToString());
Login.SetValue("ServerName", ConfigurationManager.AppSettings["ServerName"].ToString());
Login.SetValue("ImageServerName", ConfigurationManager.AppSettings["ImageServerName"].ToString());
Login.Close();
Microsoft.Win32.RegistryKey Login2;
Login2 = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ConfigurationManager.AppSettings["Wow6432NodeLogin"].ToString());
Login2.SetValue("ServerName", ConfigurationManager.AppSettings["Wow6432NodeServerName"].ToString());
Login2.SetValue("ImageServerName", ConfigurationManager.AppSettings["Wow6432NodeImageServerName"].ToString());
Login2.Close();
}
}
I think there's is an error somewhere. But no exception is thrown. The catch block never gets hit.
I'm running it as Admin. I even ran it with no admin privileges, but still no errors when it supposed to show "access denied" or something. I restarted the laptop to see the changes applied, but still no success.
I used this code to read the recently added values and I can see the keys. But somehow the changes are not being applied.
Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(ConfigurationManager.AppSettings["Login"].ToString());
Object o = key.GetValue("ServerName");
Console.WriteLine(o.ToString());
I'm using .Net 4.5.2, building for Any CPU, SO: Windows 7.
Do I need to commit the changes or something?
As suggested by #PieterWitvoet in the comments, you might want to use OpenBaseKey() instead. This is to avoid WoW64 registry redirection as explained here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384182.aspx
Note the small print at the end of that page:
To examine the effect of running this example with regedit, inspect the values of the following keys. Note that applications should avoid using Wow6432Node in hard-coded registry paths.
So, here is an example of what you could be doing instead:
static void Edit()
{
using (var root = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
using (RegistryKey key = root.CreateSubKey("SOFTWARE\\Homebrew-Testing"))
{
key.SetValue("ServerName", "ServerName-Value");
key.SetValue("ImageServerName", "ImageServerName-Value");
}
}
Notice how you can ditch the second part of your code that deals specifically with Wow6432Node, which is recommended against in the article linked above.
The documentation for RegistryView states that if you request the 64-bit view on a 32-bit operating system, the returned keys will be in the 32-bit view.
I hope this helps. Best of luck.
Related
My C# application license manager is returning NULL when checking for a Key's existence even though the key exists and my application is installed. I have tried running as an Administrator and add or removing backslashes in the Key path.
RegistryKey LitenUpKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\LitenUp\NIT", false);
if (LitenUpKey == null) {
// Registry Key NOT Found
return false;
}
NOTE: I am building as x64!
As #RbMm pointed out, the issues was in registry reflection between 32 bit and 64 bit. The following question showed me how to choose which view I saw. Here it is.
I'm getting reported errors from users who are receiving the error "System.Security.SecurityException, Requested registry access is not allowed." when trying to read the registry. I can't think why someone would not have permission to read the registry and I'm unable to reproduce the problem on my Windows 7 PC. Affected users are running .NET 4.0
Here's the C# code I'm using:
var baseReg = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var key = baseReg.OpenSubKey(RegKey, RegistryKeyPermissionCheck.ReadSubTree);
if (key != null)
{
var value = key.GetValue("DisableAutoUpdate", 0);
if (value != null)
{
updatesDisabled = Convert.ToBoolean(value);
}
}
EDIT:
I've checked permissions on the registry key concerned for the affected user and standard Users have read permission for that key.
EDIT 2 and SOLUTION:
According to the affected user, installing .NET 4.5.2 resolves the problem! I'm not sure why.
Thanks to #nozzleman's answer below this is fixed by forcing it to open the key as read-only. However it's odd that .NET 4.0 as 4.5.2 appear to behave differently.
There is an overload of the OpenSubKey(..)-Method that allows to add a third parameter. You could try passing RegistryRights.ReadKey with that one and see if that solves the issue.
baseReg.OpenSubKey(
RegKey,
RegistryKeyPermissionCheck.ReadSubTree
RegistryRights.ReadKey);
Alternatively, try the other overload accepting 2 parameters like so
baseReg.OpenSubKey(RegKey, false);
This leads to opening the subkey readonly, and you dont neet to read the whole sub tree in the given szenario..
Before you try to answer this with, "Do a quick Google search." I'd like to point out that I have already. Here is the situation, I have the following method that attempts to modify a registry key value. The problem I'm getting is that when executed, it throws an UnauthorizedAccessException even though I've opened the key as writeable. I'm running Visual Studio as administrator and even tried to make a small .exe with a manifest file forcing it to run as admin that will execute the code with no luck. The key already exists, it doesn't try to go into the CreateKey method. Here is the block of code.
Path = "S-1-5-21-1644491937-1078145449-682003330-5490\Software\Microsoft\Windows\CurrentVersion\Policies\System"
Key = "DisableTaskMgr"
NewValue = 1
public OperationResult ModifyKey()
{
OperationResult result = new OperationResult();
if (!Path.IsNullOrEmptyTrim())
{
if (!Key.IsNullOrEmptyTrim())
{
try
{
var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, true);
if (key != null)
{
key.SetValue(Key, NewValue);
key.Close();
}
else
{
result = CreateKey();
}
}
catch (Exception ex)
{
result.SetFail("Error accessing registry", ex);
}
}
else
{
result.SetFail("Registry key was null");
}
}
else
{
result.SetFail("Registry path was null");
}
return result;
}
Do I have to manually walk down the registry tree setting each OpenSubKey call to writeable? I tried this as well, still threw the same error...
in the var for your key
var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, true);
change to
var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, RegistryKeyPermissionCheck.ReadWriteSubTree);
Have you tried setting the accessrule and permissions?
string user = Environment.UserDomainName + "\\" + Environment.UserName;
RegistryAccessRule rule = new RegistryAccessRule(user,
RegistryRights.FullControl,
AccessControlType.Allow);
RegistrySecurity security = new RegistrySecurity();
security.AddAccessRule(rule);
var key = Microsoft.Win32.Registry.Users.OpenSubKey(subKeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
key.SetAccessControl(security);
One possible issue that I see with your code is that the Path variable is being set to a string that doesn't escape the \ characters. How about something like:
Path = #"S-1-5-21-1644491937-1078145449-682003330-5490\Software\Microsoft\Windows\CurrentVersion\Policies\System";
As a last ditch effort to figure out what was going on, I created a simple service to test this code that will run as the local system account. It's the highest privileges I could think of to try and run the code with. Running the code with these permissions worked.
Special thanks go out to 0_____0 and Charleh for pointing out the anti-virus as well. I checked the logs and it turns out it was trying to quarantine my changes. I guess even it won't stop the System user from making these changes though.
Special thanks go out to Sorceri as well for helping me research this so much.
In conclusion, if you're having intermittent, extremely odd behavior, check your virus scanner and permissions.
I ran into the same problem recently. So I tried a few things and instead of calling key.SetValue(Key, NewValue) simply calling create function solved my problem. That is;
Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.Users.CreateSubKey(Path);
key1.SetValue(Key, NewValue);
CreateSubKey call doesn't delete the current entry but provided with the ability to write without exception. I hope that helps.
Only set grants to dword. You must to open Registry and at the last folder path, rigth click over it and set Grants, and select All Aplications and check Total Control. I hope to help you.
just Registry.SetValue(sub_key, key, value);
Example:
Registry.SetValue(
#"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
"MyApp",
Application.ExecutablePath);
How can I get the number of times a program has previously run in c# without keeping a file and tallying. Is there a Application class or something in c# to check the count.
Please give a detailed explantion as i know nothing about it.This is A windows console application not windows forms.
You can do that my creating an Entry in the Registry. And another way is by using an Application Settings.
But I prefer Application Settings because it has less task to do.
See HERE: Creating an Application Settings.
Tutorial From Youtube
Recent versions of Windows automatically maintain this information in the registry under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist.
The data is obfuscated with ROT13, but that's easy to "decrypt". A free utility (with source code) is available and can serve as your starting point.
You could send a message to a database or webservice every time the program starts up (assuming there's a network connection).
You could keep a count on some form of hardware thet's not a standard storage device (therefore not technically being a file).
You could make a registry entry that you keep the count in (if you ignore the fact that the registry entry is, at some level, persisted into a file somewhere).
You could just have a file somewhere that keeps track of the count. Not sure why you're so opposed to this one in the first place....
If you are running a Winforms application, the you can easily use the Application Settings. Right click on your Solution Name --> Properties --> Settings Tab. More info and tutorial here.
Then, every time your program starts, increment this setting and save it.
Ref: Count the number of times the Program has been launched
In my knowledge Windows does not keep this information for you. You would have to tally the value somewhere (file, database, registry setting).
Better way is Application Settings as:
Create setting in app.config and then use it as:
Properties.Settings.Default.FirstUserSetting = "abc";
then, you usually do this in the Closing event handler of the main form. The following statement to Save settings method.
Properties.Settings.Default.Save();
Implementation using Registry:
static string AppRegyPath = "Software\\Cheeso\\ApplicationName";
static string rvn_Runs = "Runs";
private Microsoft.Win32.RegistryKey _appCuKey;
public Microsoft.Win32.RegistryKey AppCuKey
{
get
{
if (_appCuKey == null)
{
_appCuKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(AppRegyPath, true);
if (_appCuKey == null)
_appCuKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(AppRegyPath);
}
return _appCuKey;
}
set { _appCuKey = null; }
}
public int UpdateRunCount()
{
int x = (Int32)AppCuKey.GetValue(rvn_Runs, 0);
x++;
AppCuKey.SetValue(rvn_Runs, x);
return x;
}
If it's a WinForms app, you can hook the Form's OnClosing event to run UpdateCount.
Then Check tutorial to Read, write and delete from registry with C#
I have created the following registry key (copied through regedit):
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\test
I would like to now delete this registry key, and so... I have been using the following code and am running into a small error.
RegistryKey regKey;
string regPath_Key = #"Software\Microsoft\Windows\CurrentVersion\test";
regKey = Registry.CurrentUser.OpenSubKey(regPath_Key, true);
if(regKey != null) // Always returns null, even though the key does exist.
{
Registry.CurrentUser.DeleteSubKey(regPath_Key, true);
}
The issue I am having is that the line if(regKey != null) always returns null! I have gone back and checked that the key does in fact exist multiple times - but still the same result. I am going to assume my code has issues somewhere?
Could it be that you are on a 64 bit machine and your project is set to x86 architecture? in that case, verify that the key you state exists under HKCU\Software\Wow6432Node... as every path is redirected to this 32 bit process registry...
You should not include HKEY_CURRENT_USER in the string you pass to Registry.CurrentUser.OpenSubKey(). Instead use
string regPath_Key = #"Software\Microsoft\Windows\CurrentVersion\test";