I'm trying to get a value from the registry in Windows, which sits under several branches:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\...
Given the following code:
RegistryKey openSubKey = settings.OpenSubKey(
#"\\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\DefaultSpoolDirectory");
openSubKey.SetValue("printername", "");
Where settings is set to LocalMachine in Microsoft.Win32.Registry.
However, I'd get null after the first line of code. What gives?
Two mistakes, \HKEY_LOCAL_MACHINE doesn't belong there, you should use Registry.LocalMachine instead. And DefaultSpoolDirectory doesn't belong there, it is a value, not a key.
The SetValue() arguments do not look happy either. If you want to add a printer (don't) then you'll need to add a key, not a value.
try removing "\hkey_local_machine"
Richard's answer seems correct, but just to inform you a little further, you can access the LocalMachine scope of the registry through the Registry.LocalMachine property - check this MSDN link for details. For an example, try this:
var openSubKey = Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers");
Related
DirectorySecurity fs;
string FolderPath = "C:/Program Files";
fs = Directory.GetAccessControl(FolderPath, AccessControlSections.All);
foreach (FileSystemAccessRule fileSystemAccessRule in fs.GetAccessRules(true,true,typeof(System.Security.Principal.NTAccount)))
{
userNameDomain = fileSystemAccessRule.IdentityReference.Value;
userRights = fileSystemAccessRule.FileSystemRights.ToString();
string[] row = { userNameDomain, userRights };
var listViewItem = new ListViewItem(row);
lv_perm.Items.Add(listViewItem);
}
When doing this on "regular" files and folders (ex: C:/Users/Julien/Desktop/New folder), everything seems good:
ListView:
But, when I'm doing this on a folder with "special" rights (ex: C:/Program Files), I got duplicate IdentityReference.Value associated to strange numbers for rights:
Listview not good:
I don't have as many rights entries with strange numbers when I open the Permissions tab in C:/Program Files properties.
Maybe I'm doing something bad?
EDIT: From that page Here:
Using .NET you may think that determining which permissions are
assigned to a directory/file should be quite easy, as there is a
FileSystemRights Enum defined that seems to contain every possible
permission that a file/directory can have and calling
AccessRule.FileSystemRights returns a combination of these values.
However, you will soon come across some permissions where the value in
this property does not match any of the values in the FileSystemRights
Enum (I do wish they wouldn’t name some properties with the same name
as a Type but hey).
The end result of this is that for some files/directories you simply
cannot determine which permissions are assigned to them. If you do
AccessRule.FileSystemRights.ToString then for these values all you see
is a number rather than a description (e.g Modify, Delete, FullControl
etc). Common numbers you might see are:
-1610612736, –536805376, and 268435456
To work out what these permissions actually are, you need to look at
which bits are set when you treat that number as 32 separate bits
rather than as an Integer (as Integers are 32 bits long), and compare
them to this diagram:
msdn.microsoft.com/en-us/library/aa374896(v=vs.85).aspx
So for example, -1610612736 has the first bit and the third bit set,
which means it is GENERIC_READ combined with GENERIC_EXECUTE. So now
you can convert these generic permissions into the specific file
system permissions that they correspond to.
You can see which permissions each generic permission maps to here:
msdn.microsoft.com/en-us/library/aa364399.aspx. Just be aware
that STANDARD_RIGHTS_READ, STANDARD_RIGHTS_EXECUTE and
STANDARD_RIGHTS_WRITE are all the same thing (no idea why, seems
strange to me) and actually all equal the
FileSystemRights.ReadPermissions value.
So I think, because GetAccessRules are unable to group for ex:
NT SERVICE\TrustedInstaller FullControl
and
NT SERVICE\TrustedInstaller 268435456
He create 2 distinct entry.
I have to correct the FileSystemRights so they fit to the enumeration.
268435456 - FullControl
-536805376 - Modify, Synchronize
-1610612736 - ReadAndExecute, Synchronize
This issue exist since 2014. And still exist today.
You're not doing anything bad. The access mask is actually represented as an int internally (and on the file system), but the enum FileSystemRights is incomplete.
Therefore the visualizers and those functions converting a FileSystemRights value to a string will be at a loss and simply give you the numeric value (but as a string).
This means in order to make sense of them you'd have to inspect WinNT.h (from the Windows SDK) and look up all the possible access mask values - including generic ones - and provide a manual way of converting the numeric representation to a more human-readable string.
What you encountered are two distinct ACEs with different (but semantically equivalent) access masks, it seems. This is perfectly fine and happens in the wild (as your screenshot proves!). The .NET framework, however, chooses to ignore the issue.
If you look at the ACL with Powershell's Get-Acl or with icacls (a tool which has been on board since Windows 2000), you can see that there are potentially differences in how the individual ACEs are inherited or propagate down the filesystem hierarchy.
Another alternative would be to call the MapGenericMask() and have it perform the mapping. So when you would give it GENERIC_ALL (== 0x10000000) it would return 0x001f01ff, which corresponds to FileSystemRights.FullControl. This way you could "bend" the generic access mask into a form understood by the .NET framework.
I've been trying out the most of the Enviroment.SpecialFolder enumeration, but I think there isn't any way of what I'd like to accomplish with the enumeration only. Using the string.Substring() method brought me the farest, yet.
I try to get just the system partition path, where windows is actually installed. On machine A it might be C:\, on machine B it might be D:\.
The most sufficent solution, I found so far was
var path = Environment.GetFolderPath(Environment.SpecialFolder.Windows)
.Substring(0, 3);
Is there a better way to do this? Thanks.
To get the drive, use Path.GetPathRoot. See http://msdn.microsoft.com/en-us/library/system.io.path.getpathroot.aspx
var root = Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.Windows));
If you need "disk where Environment.SpecialFolder.Windows" your sample is ok.
You may want to use Path.GetPathRoot instead of Susbstring...
Note that you probably should not write anything to the root drive yourself (if your program is designed to behave nice).
I would like to read value in the registry using C#, if the values are not in the registry I create it. I have a reading problem:
RegistryKey regKey1 = Registry.CurrentUser;
regKey1 = regKey1.CreateSubKey(#"SOFTWARE\PNMDISPATCHER");
if (regKey1 != null)
{
textBoxTaux1.Text = regKey1.GetValue("Taux1").ToString();
}
I have the NullReferenceException when execute the GetValue function.
My values are in the registry, so why i get this error?
Looks like the RegistryKey.GetValue is returning null and cannot do .ToString()
Taken from MSDN for RegistryKey.GetValue:
Retrieves the value associated with the specified name. Returns null
if the name/value pair does not exist in the registry.
Well, apparently you didn't get the path right..
GetValue returns a Null when the key isn't found. Also check http://msdn.microsoft.com/en-us/library/fdf576x1
Can you debug through it and double check that the path you want to see, is indeed in the regKey1 variable at the textbox line?
Perhaps the NullReferenceException is for textBoxTaux1? Please post the call stack for the exception which should make this clear. You can use Exception.ToString() to get this.
This is a very general and noob question, but I am a noob with real programming so...
How can I set a Boolean setting and store that setting so that when you exit the app and come back the setting is how the user left it? I also need to know how to read that setting and enable features based on them.
I plan to have two settings in my app, one for location and one for turning off an alert on attempting to exit the app (I know this is considered bad by most people, but trust me, it makes sense for this app).
I have no idea how to do this, things like this and cookies have always confounded me, so a good explanation would be greatly appreciated.
My app is in C# and XAML if that helps.
Might want to take a look at this article: http://dotnet.dzone.com/articles/using-application-settings
And this other SO question: When should I save settings on Windows Phone 7?
Use this code:
// save value
IsolatedStorageSettings.ApplicationSettings["MyName"] = true;
// read value
var val = IsolatedStorageSettings.ApplicationSettings.Contains("MyName")
? (bool) IsolatedStorageSettings.ApplicationSettings["MyName"]
: false; // false is default value
I like MSDN binding-based example:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff769510(v=vs.105).aspx
(Thanks to Dmitry T. for the link on SO.)
I have a legacy (I didn't build it) application running on an x64 environment (Win7). I have a sneaking suspicion it was run on a 32-bit environment before.
Anyway, I see calls to Registry.GetValue(key, value, default).
It seems like the default value is ignored.
Check out this crazy code:
// Up above the sky, so high
using Microsoft.Win32;
// ...
string location = "HKEY_LOCAL_MACHINE\SOFTWARE\..."; // ...
// ...
string registryValue = (string)Registry.GetValue(location, "Uri", "http://localhost/");
if (string.isNullOrEmpty(registryValue) {
throw new Exception("What the ... ?!");
}
In a comparable example, the exception is seriously being thrown. (Actually, a null-reference exception appears despite the default value).
And I checked that I have the registry keys all the way up to the last level; they're all in my registry.
This works for someone, but not for me.
Is this a bug? What's going on here?
Most likely you are being caught out by registry redirection. You have a 32 bit process running on a 64 bit system. So HKLM\Software is redirected to HKLM\Software\Wow6432Node.
When the key does not exist, the Registry.GetValue returns null rather than the default value and so the exception is thrown.
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.
The default value is only returned if the specified key (that is the first parameter, i.e. location in your example) is found but a value with the specified name (the second parameter, "Uri" in your example) does not exist within that key.
If the key itself does not exist a null reference is returned.
This is fairly well documented on MSDN.
Probably the key you are looking for does not exist, probably because you are running on a 64-bit environment now which means that in case your application is a 32-bit process the HKLM\Software key gets mapped to HKLM\Software\Wow6432Node.
I know this is ancient, but in case anybody else stumbles upon this issue, I found an approach that works well for me. I'm using OpenSubKey, instead of GetValue.
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\MyProduct");
string data = key.GetValue("MyValue") as string;
The registry's terminology caused me some confusion. It is not simply a key -> value store, it is more like key -> value -> data.
I've no idea why but i solved using
My.Computer.Registry.CurrentUser.GetValue("Software\Mykey","Default Value")
instead of
My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software","Mykey","Default Value")
If the key doesn't exist the first example returns "Default Value", the second a null object!