Подтвердить что ты не робот

Как проверить, разрешено ли пользователю читать или записывать определенный раздел реестра?

Кто-нибудь знает, как я могу программно проверить (используя С#), сможет ли моя программа читать/записывать определенный раздел реестра (в частности: "ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \Microsoft\Windows\CurrentVersion\Run" )?

Я спрашиваю, потому что моя программа имеет возможность включить или отключить поведение "запустить при запуске". Я хочу отключить этот параметр, если текущему пользователю не разрешено вносить изменения в реестр. Этот ключ всегда может быть написан текущим пользователем или есть вероятность, что он заблокирован? Если последний, как это проверить?

Я видел несколько противоречивых способов проверки разрешений реестра, но в основном я не могу найти способ проверить конкретный ключ, прежде чем пытаться его прочитать. Я предпочел бы выполнить проверку перед доступом к ключу, чем пытаться получить к нему доступ и получить исключение.

Любая помощь очень ценится.

Tom

4b9b3361

Ответ 1

Класс RegistryPermission определяет разрешения безопасности для ключей reg. Чтобы проверить, есть ли у вас доступ на запись к разрешению, которое вы используете, следующим образом:

RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");

Затем вы использовали метод "Спрос" в try/catch и return on failure (повышение исключения безопасности). При успешном выполнении вы будете продолжать и выполнять свое обновление. Хотя это не совсем то, что вы хотите, проверка разрешений перед доступом, это общепринятый способ обеспечения того, чтобы у вас были разрешения, необходимые для работы с ключами. В полностью структурированном виде это будет соответствовать:

try
{
    RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
    perm1.Demand();
}
catch (System.Security.SecurityException ex)
{
    return;
}

//Do your reg updates here

EDIT: Размышляя над тем, что я упомянул в комментарии, здесь приведены методы расширения класса RegistryPermission для проверки разрешений:

using System.Security.Permissions;
using System.Security;

public static class RegistryExtensions
{
    public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(accessLevel, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }

    public static bool CanWriteKey(this RegistryPermission reg, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }

    public static bool CanReadKey(this RegistryPermission reg, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }
}

Ответ 2

Одна вещь, которую вы должны знать о разрешениях, заключается в том, что они нестабильны. Это означает, что вы можете выполнить проверку безопасности в разделе реестра, попытаться добавить свое значение только в том случае, если проверка прошла, а затем все еще сбой с недостаточным доступом, поскольку разрешения были изменены между ними, когда вы сделали чек, и когда вы действовали на Результаты. Это возможно, даже если они являются последовательными операторами в вашей программе.

Предоставленные разрешения безопасности, как правило, относительно стабильны, но шанс все еще существует. Это означает, что у вас должен быть код для обработки исключения безопасности, и если вам это нужно, в любом случае на самом деле нет никакого смысла делать чек. Вместо этого положите свое время на то, чтобы сделать обработчик исключений немного лучше.

Тем не менее, "boo" для любого приложения, которое хочет запустить что-то при запуске. YAGNI.

Ответ 3

Я думаю, вам лучше всего просто попытаться добавить свое значение к ключу и обработать неудачу изящно, сообщив пользователю, что у них недостаточно прав для этого.

Если вы пишете какой-то административный инструмент, который всегда должен запускаться администратором, вы должны указать, что в manifest. Таким образом ваше приложение будет повышаться при запуске (через приглашение UAC).

Ответ 4

Простейшим вариантом является попытка открыть ключ с доступом для записи и посмотреть, получаете ли вы его. Запомните close ключ.

bool fWriteAccess;
try {
    Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close();
    fWriteAccess = True;
} catch (SecurityException) {
    fWriteAccess = False;
}

Ответ 5

Я не уверен, как это сделать с С#, но с Win32 вы бы использовали RegGetKeySecurity(). Может быть, есть обертка С#? В противном случае используйте P/Invoke.

Ответ 6

Просто попробуйте открыть раздел реестра с разрешениями WRITE.

Тем не менее, то, что говорили другие, справедливо: нет способа узнать, будет ли операция успешной, если вы не попробуете ее. Возможно, кто-то удалил клавишу Run. Возможно, реестр превысит выделенную память. Возможно, диск вышел из строя.