Autorizzazioni di ServiceController in Windows 7

Ho un’applicazione che consiste in un servizio e un eseguibile. Essenzialmente è un’applicazione di moduli che è responsabile per l’avvio e l’arresto di un servizio in circostanze specifiche.

Su Windows XP l’applicazione gestisce questa multa usando il seguente codice:

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

Ma su Windows 7, anche se ho avviato l’applicazione come amministratore, ottengo la seguente eccezione:

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

C’è qualcosa che posso fare a livello di programmazione per risolvere questo?

Quando dici di aver avviato l’applicazione come amministratore, intendi con un account nel gruppo Administrators o tramite un prompt UAC che richiede le credenziali dell’amministratore? Senza il prompt delle credenziali UAC (o effettivamente eseguito come account Administrator, non un account all’interno del gruppo Administrators), l’applicazione non dispone delle autorizzazioni per modificare i servizi, quindi l’eccezione che si sta verificando è corretta.

Questo bit di codice di esempio può verificare se l’applicazione è in esecuzione come amministratore e, in caso contrario, avviare un prompt 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; } } 

Puoi anche provare a impostare il controllo dell’account utente per la tua applicazione su “Esegui come amministratore” nel codice.

Cordiali saluti, se non capisci perché non funziona in Vista o 7 anche se l’utente corrente è nel gruppo degli amministratori, ecco cosa MSDN ha da dire

In Windows Vista, Controllo dell’account utente (UAC) determina i privilegi di un utente. Se si è membri del gruppo Amministratori incorporati, vengono assegnati due token di accesso in fase di esecuzione: un token di accesso utente standard e un token di accesso amministratore. Per impostazione predefinita, sei nel ruolo utente standard. Quando si tenta di eseguire un’attività che richiede privilegi amministrativi, è ansible elevare dynamicmente il proprio ruolo utilizzando la finestra di dialogo Consenso. Il codice che esegue il metodo IsInRole non visualizza la finestra di dialogo Consenso. Il codice restituisce false se si è nel ruolo utente standard, anche se si è nel gruppo Administrators incorporato. È ansible elevare i privilegi prima di eseguire il codice facendo clic con il pulsante destro del mouse sull’icona dell’applicazione e indicando che si desidera eseguire come amministratore.

Ricordo che ero abbastanza sorpreso al primo utilizzo di 7 (non ho mai usato Vista).