Permisos de ServiceController en Windows 7

Tengo una aplicación que consiste en un servicio y un ejecutable. Básicamente, es una aplicación de formularios que se encarga de iniciar y detener un servicio en circunstancias específicas.

En Windows XP, la aplicación maneja esta multa utilizando el siguiente código:

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

Pero en Windows 7, aunque inicié la aplicación como administrador, recibo la siguiente excepción:

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

¿Hay algo que pueda hacer programáticamente para resolver esto?

Cuando dice que comenzó la aplicación como administrador, ¿quiere decir con una cuenta en el grupo de administradores o mediante un aviso de UAC que solicita credenciales de administrador? Sin la solicitud de credenciales UAC (o en realidad se ejecuta como la cuenta de administrador, no como una cuenta dentro del grupo Administradores), su aplicación no tiene permisos para modificar los servicios, por lo que la excepción que está viendo es correcta.

Este pequeño código de ejemplo puede verificar si su aplicación se está ejecutando como administrador, y si no, inicie un aviso de 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; } } 

También puede intentar configurar el UAC de su aplicación en “Ejecutar como administrador” en el código.

FYI, si no entiende por qué no funciona en Vista o en 7, incluso si el usuario actual está en el grupo de administradores, esto es lo que MSDN tiene que decir

En Windows Vista, el Control de cuentas de usuario (UAC) determina los privilegios de un usuario. Si es miembro del grupo Administradores integrados, tiene asignados dos tokens de acceso en tiempo de ejecución: un token de acceso de usuario estándar y un token de acceso de administrador. Por defecto, usted está en la función de usuario estándar. Cuando intenta realizar una tarea que requiere privilegios administrativos, puede elevar dinámicamente su función mediante el cuadro de diálogo Consentimiento. El código que ejecuta el método IsInRole no muestra el cuadro de diálogo de Consentimiento. El código devuelve falso si está en la función de usuario estándar, incluso si está en el grupo de administradores integrados. Puede elevar sus privilegios antes de ejecutar el código haciendo clic con el botón derecho en el icono de la aplicación e indicando que desea ejecutarlo como administrador.

Recuerdo que estaba bastante sorprendido el 1ro cuando usé 7 (nunca usé Vista).