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

Разрешения ServiceController в Windows 7

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

В Windows XP приложение управляет этим штрафом, используя следующий код:

ServiceController controller = new ServiceController();
controller.MachineName = ".";
controller.ServiceName = "XXXXXXXXXX";
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 10));
controller.Start();

Но в Windows 7, хотя я запустил приложение в качестве администратора, я получаю следующее исключение:

System.InvalidOperationException: Cannot open XXXXXXXXXXXXX service on computer '.'. ---> System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
   at System.ServiceProcess.ServiceController.Start(String[] args)
   at System.ServiceProcess.ServiceController.Start()

Есть ли что-нибудь, что я могу сделать программно, чтобы решить эту проблему?

4b9b3361

Ответ 1

Когда вы говорите, что вы запустили приложение в качестве администратора, вы имеете в виду под учетной записью в группе "Администраторы" или с помощью приглашения UAC, запрашивающего учетные данные администратора? Без приглашения учетных данных UAC (или фактически выполняемого как учетная запись администратора, а не учетной записи в группе "Администраторы" ) ваше приложение не имеет прав на изменение служб, поэтому исключение, которое вы видите, является правильным.

Этот бит примера кода может проверить, работает ли ваше приложение как администратор, а если нет, запустите приглашение UAC.

public static class VistaSecurity
{
    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();

        if (null != identity)
        {
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        return false;
    }

    public static Process RunProcess(string name, string arguments)
    {
        string path = Path.GetDirectoryName(name);

        if (String.IsNullOrEmpty(path))
        {
            path = Environment.CurrentDirectory;
        }

        ProcessStartInfo info = new ProcessStartInfo
        {
            UseShellExecute = true,
            WorkingDirectory = path,
            FileName = name,
            Arguments = arguments
        };

        if (!IsAdministrator())
        {
            info.Verb = "runas";
        }

        try
        {
            return Process.Start(info);
        }

        catch (Win32Exception ex)
        {
            Trace.WriteLine(ex);
        }

        return null;
    }
}

Ответ 3

FYI, если вы не понимаете, почему он не работает в Vista или 7, даже если текущий пользователь находится в группе администратора, вот что MSDN должно сказать

В Windows Vista контроль учетных записей пользователей (UAC) определяет привилегии пользователя. Если вы являетесь членом группы "Встроенные администраторы", вам назначаются два токена доступа во время выполнения: стандартный токен доступа пользователя и токен доступа администратора. По умолчанию вы находитесь в стандартной роли пользователя. При попытке выполнить задачу, требующую административных прав, вы можете динамически повышать свою роль, используя диалоговое окно Согласия. Код, который выполняет метод IsInRole, не отображает диалоговое окно Согласия. Код возвращает false, если вы находитесь в стандартной пользовательской роли, даже если вы находитесь в группе "Встроенные администраторы". Вы можете повысить свои привилегии перед выполнением кода, щелкнув правой кнопкой мыши значок приложения и указав, что вы хотите запускать его как администратора.

Помню, я был очень удивлен 1-м, когда использовал 7 (я никогда не использовал Vista).