Что не так с Registry.GetValue? - PullRequest
8 голосов
/ 10 марта 2011

Я пытаюсь получить значение реестра:

var value = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography", "MachineGuid", 0);

В Windows XP все в порядке, но в Windows 7 возвращает 0. В HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography с помощью regedit я вижу MachineGuid, но если я запускаю

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree).GetValueNames();

keys.Length - это 0.

Что я делаю не так?С другими значениями все нормально в обеих ОС.

Ответы [ 4 ]

23 голосов
/ 20 октября 2011

Проблема в том, что вы, вероятно, компилируете решение как x86, если вы компилируете как x64, вы можете прочитать значения.

Попробуйте следующий код, скомпилированный как x86 и x64:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("MachineGUID:" + MachineGUID);

        Console.ReadKey();
    }

    public static string MachineGUID
    {
        get
        {
            Guid guidMachineGUID;
            if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography") != null)
            {
                if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid") != null)
                {
                    guidMachineGUID = new Guid(Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid").ToString());
                    return guidMachineGUID.ToString();
                }
            }
            return null;
        }
    }
}

Вы можете узнать больше о Доступ к альтернативному представлению реестра .

Вы можете найти в здесь способ чтения значений в x86 и x64.

7 голосов
/ 10 марта 2011

Вероятно, это связано с UAC (контроль учетных записей пользователей).Дополнительный уровень защиты для Windows Vista и Windows 7.

Вам потребуется запросить разрешения в реестре.

РЕДАКТИРОВАТЬ : Ваш код прямо сейчас:

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE")
    .OpenSubKey("Microsoft")
    .OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
    .GetValueNames();

Запрашивает только разрешения для подраздела Криптография, возможно, это вызывает проблему (по крайней мере, у меня это было один раз), поэтому новый код будет:

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree)
    .OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree)
    .OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
    .GetValueNames();

EDIT2:
Я прикрепил к нему отладчик, на этот код:

var key1 = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree);
var key2 = key1.OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree);
var key3 = key2.OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
var key4 = key3.GetValueNames();

Оказывается, вы можете прочитать это конкретное значение, по крайней мере, это мое предположение, потому что все данные верныДо тех пор, пока я не открою ключ 3, значение ValueCount будет равно нулю вместо ожидаемого 1.

Я думаю, что это специальное значение, которое защищено.

6 голосов
/ 10 марта 2011

Вы говорите, что находитесь на 64-битной Windows: ваше приложение 32-битное? Если это так, то, вероятно, на него влияет перенаправление реестра и он смотрит на HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography. Возможно, вам придется P / Invoke, чтобы обойти это: http://msdn.microsoft.com/en-us/library/aa384129.aspx.

3 голосов
/ 10 марта 2011

Если вы не являетесь администратором, у вас есть разрешение только на чтение HKLM. Вам нужно открыть ключ только для чтения. Не уверен, как это сделать с классом реестра .NET; напрямую через API вы используете RegOpenKeyEx () с флагом KEY_READ.

РЕДАКТИРОВАТЬ: После проверки MSDN, я вижу, что OpenSubKey () открывает только для чтения и возвращает содержимое, если это успешно, и ничего, если это не удается. Так как вы объединяете несколько вызовов OpenSubKey, скорее всего, один из них не работает, что приводит к сбою других. Попробуйте разбить их на отдельные вызовы и проверить возвращаемые промежуточные значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...