2010-10-08 28 views
12

Mam aplikację, która składa się z usługi i pliku wykonywalnego. Zasadniczo jest to aplikacja formularzy odpowiedzialna za uruchamianie i zatrzymywanie usługi w określonych okolicznościach.Uprawnienia ServiceController w systemie Windows 7

W systemie Windows XP aplikacja zarządza tym grzywny za pomocą następującego kodu:

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

Ale w systemie Windows 7, choć zacząłem aplikację jako administrator, pojawia się następujący wyjątek:

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

Czy jest coś, co mogę zrobić programowo, aby rozwiązać ten problem?

Odpowiedz

13

Kiedy mówisz, że aplikacja została uruchomiona jako Administrator, masz na myśli pod kontem w grupie Administratorzy lub za pośrednictwem monitu UAC, który żąda poświadczeń administratora? Bez pytania o poświadczenia UAC (lub faktycznie działającego jako konto administratora, a nie konto w grupie Administratorzy), aplikacja nie ma uprawnień do modyfikowania usług, więc wyjątek, który widzisz, jest poprawny.

Ten przykładowy kod może sprawdzić, czy aplikacja działa jako administrator, a jeśli nie, uruchom monit 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

Przepraszam, że byłem głupcem - używam skrótu do uruchomienia i ustawiłem na jednej z moich maszyn testowych, aby ten skrót działał jako administrator (i otrzymałem monit o UAC), ale na maszynie otrzymywałem ten wyjątek. t odpowiednio zmodyfikował skrót. –

1

FYI, jeśli nie rozumiem, dlaczego to nie działa w Vista lub 7, nawet jeśli bieżący użytkownik jest w grupie administratora, oto co MSDN ma do powiedzenia

W systemie Windows Vista, konto użytkownika Kontrola (UAC) określa uprawnienia użytkownika. Jeśli jesteś członkiem wbudowanej grupy Administratorzy, masz przydzielone dwa tokeny dostępu działającego: standardowy token dostępu użytkownika i token dostępu administratora. Domyślnie jesteś w standardowej roli użytkownika. Podczas próby wykonania zadania wymagającego uprawnień administratora można dynamicznie podnieść swoją rolę, korzystając z okna dialogowego Zgoda. Kod wykonujący metodę IsInRole nie wyświetla okna dialogowego Zgoda. Kod zwraca wartość false, jeśli jesteś w standardowej roli użytkownika, nawet jeśli jesteś w grupie wbudowanych administratorów. Możesz podnieść swoje uprawnienia przed uruchomieniem kodu, klikając prawym przyciskiem myszy ikonę aplikacji i wskazując, że chcesz działać jako administrator.

Pamiętam, że byłem bardzo zaskoczony jako pierwszy przy użyciu 7 (nigdy nie korzystałem z Vista).

Powiązane problemy