Ошибка при попытке установить значение DWORD в реестре windows с помощью C # - PullRequest
1 голос
/ 14 марта 2020

Я пишу код, который устанавливает значение в реестре Windows. когда я устанавливаю это значение вручную, оно работает как положено; когда я хочу установить значение программно, однако, это дает ошибку. Значение, которое я хочу определить, является типом значения DWORD "4294967295". Когда я определяю это в скрипте, он говорит, что DWORD не поддерживает это значение. И, тем не менее, я могу назначить это точное значение с помощью программы, которую я использую для обновления реестра вручную.

Вот мой код:

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

1 Ответ

2 голосов
/ 14 марта 2020

Как вы, вероятно, знаете, DWORD хранится как 32-разрядное двоичное число . Что может быть не сразу очевидно, так это то, что это без знака - и, таким образом, UInt32 (uint). В противном случае вы не сможете сохранить значение 4294967295, поскольку максимальное значение для целого числа со знаком (int) равно 2 147 483 647 .

Однако есть одна загвоздка ! Как отметил @Jimi в комментариях, SetValue() попытается выполнить Convert.ToInt32(), что приведет к переполнению с любым значением выше Int32.MaxValue - то есть полученной вами ошибке. Можно было бы ожидать, что будет использовать Convert.ToUInt32(), но, как @Jimi также обнаружил, это известная ошибка в методе , которую Microsoft не может исправить из-за проблем обратной совместимости.

Вместо метод SetValue() преобразует Int32 (int) со знаком в 32-разрядное двоичное число без знака со значениями 0…2147483647 остается как есть, но значения -2147483647…-1 сохраняются в диапазоне 2147483648…4294967295.

Это двоичное преобразование немного запутанно, если вы думаете об этом как целое число со знаком. Но, к счастью, вы можете использовать встроенное ключевое слово C # unchecked() , чтобы разрешить переполнение и эффективно обработать ваш uint как подписанный int в этих диапазонах:

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

Это действительно удобно, потому что позволяет вам продолжать работать со стандартным UInt32 (uint) диапазоном 0…4294967295, точно так же, как вы, например, с помощью RegEdit, без необходимости думать о том, как происходит двоичное преобразование. обрабатываются.

...