简体   繁体   中英

Error when trying to set a DWORD value in the windows registry using C #

I'm writing code that sets a value in the Windows registry. when I set that value manually, it works as expected; when I want to set the value programmatically, however, it gives an error. The value I want to define is a DWORD value type that is "4294967295". When I define that in the script, though, it says that DWORD does not support this value. And, yet, I can assign that exact value via the program I am using to manually update the registry.

Here's my code:

RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Lost in Days Studio\NO TIME", true);
key.SetValue("Current", 4294967295, RegistryValueKind.DWord);
key.Close();

As you likely know, a DWORD is stored as a 32 bit binary number . What may not be immediately obvious, though, is that it's unsigned —and, thus, a UInt32 ( uint ). Otherwise, you wouldn't be able to store a value of 4294967295 , since the maximum value for a signed integer ( int ) is 2,147,483,647 .

There's a catch, however! As @Jimi noted in the comments, SetValue() will attempt to do a Convert.ToInt32() , which will cause an overflow with any value above Int32.MaxValue —thus the error you are receiving. One would expect it to use Convert.ToUInt32() but, as @Jimi also discovered, that is a known bug in the method , which Microsoft is unable to fix due to backward compatibility concerns.

Instead , the SetValue() method converts a signed Int32 ( int ) into an unsigned 32 bit binary number, with values of 0…2147483647 remaining as is, but values of -2147483647…-1 getting saved to the 2147483648…4294967295 range.

That binary conversion is a bit convoluted if you're thinking about this as a signed integer. But, fortunately, you can use C#'s built-in unchecked() keyword to permit the overflow and effectively treat your uint as a signed int within those ranges:

key.SetValue("Current", unchecked((int)4294967295), RegistryValueKind.DWord);

This is really handy because it allows for you to continue to work with a standard UInt32 ( uint ) range of 0…4294967295 , exactly like you would via eg RegEdit, without having to think about how the binary conversion is being handled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM