Вопрос

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

В 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()

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

Это было полезно?

Решение

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

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

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;
    }
}

Другие советы

Вы также можете попробовать установить UAC для вашего приложения в "Запустить от имени администратора" в коде.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top