Разрешения ServiceController в Windows 7 - PullRequest
12 голосов
/ 08 октября 2010

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

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

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

Ответы [ 3 ]

13 голосов
/ 08 октября 2010

Когда вы говорите, что запустили приложение от имени администратора, вы имеете в виду под учетной записью в группе администраторов или через приглашение 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;
    }
}
1 голос
/ 12 октября 2011

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

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

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

1 голос
/ 24 ноября 2010

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

...