Elevando el privilegio del proceso programáticamente?

Intento instalar un servicio usando InstallUtil.exe pero invocado a través de Process.Start . Aquí está el código:

 ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath); System.Diagnostics.Process.Start (startInfo); 

donde m_strInstallUtil es la ruta de acceso completa y exe a “InstallUtil.exe” y strExePath es la ruta / nombre completo de mi servicio.

Se ejecuta la syntax de la línea de comando desde un símbolo del sistema elevado; ejecutar desde mi aplicación (utilizando el código anterior) no lo hace. Supongo que estoy lidiando con algún problema de elevación del proceso, entonces, ¿cómo podría ejecutar mi proceso en un estado elevado? ¿Necesito ver ShellExecute para esto?

Esto es todo en Windows Vista. Estoy ejecutando el proceso en el depurador VS2008 elevado a privilegio de administrador.

También intenté configurar startInfo.Verb = "runas"; pero no pareció resolver el problema.

Puede indicar que el nuevo proceso debe iniciarse con permisos elevados estableciendo la propiedad Verb de su objeto startInfo en ‘runas’, de la siguiente manera:

 startInfo.Verb = "runas"; 

Esto hará que Windows se comporte como si el proceso se hubiera iniciado desde Explorer con el comando de menú “Ejecutar como administrador”.

Esto significa que el aviso de UAC aparecerá y será necesario que el usuario lo confirme: si esto no es deseable (por ejemplo, porque ocurriría en medio de un proceso prolongado), deberá ejecutar todo el proceso de host con permisos elevados de Crear e incrustar un manifiesto de aplicación (UAC) para requerir el nivel de ejecución ‘highestAvailable’: esto hará que el aviso de UAC aparezca tan pronto como se inicie su aplicación, y hará que todos los procesos secundarios se ejecuten con permisos elevados sin pautas adicionales .

Editar: Veo que acaba de editar su pregunta para indicar que “runas” no funcionó para usted. Eso es realmente extraño, como debería (y lo hace para mí en varias aplicaciones de producción). Sin embargo, es necesario que exista el requisito de que el proceso principal se ejecute con derechos elevados mediante la incrustación del manifiesto.

Este código reúne todo lo anterior y reinicia la aplicación wpf actual con privilegios de administrador:

 if (IsAdministrator() == false) { // Restart program and run as admin var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; System.Diagnostics.Process.Start(startInfo); Application.Current.Shutdown(); return; } private static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); } // To run as admin, alter exe manifest file after building. // Or create shortcut with "as admin" checked. // Or ShellExecute(C# Process.Start) can elevate - use verb "runas". // Or an elevate vbs script can launch programs as admin. // (does not work: "runas /user:admin" from cmd-line prompts for admin pass) 

Actualización: se prefiere la forma de manifiesto de la aplicación:

Haga clic con el botón secundario en proyecto en Visual Studio, agregue el nuevo archivo de manifiesto de la aplicación, cambie el archivo para que tenga requiredAdministrator configurado como se muestra en la figura anterior.

Un problema con la forma original: si coloca el código de reinicio en app.xaml.cs OnStartup, aún puede iniciarse brevemente la ventana principal aunque se haya llamado a Shutdown. Mi ventana principal estalló si app.xaml.cs init no se ejecutó y en ciertas condiciones de carrera haría esto.

Según este artículo , solo ShellExecute verifica el manifiesto incrustado y solicita al usuario elevación si es necesario, mientras que CreateProcess y otras API no lo hacen. Espero eso ayude.

 [PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")] 

Esto lo hará sin UAC, no es necesario iniciar un nuevo proceso. Si el usuario en ejecución es miembro del grupo de administración en mi caso.

Deberías usar suplantación para elevar el estado.

 WindowsIdentity identity = new WindowsIdentity(accessToken); WindowsImpersonationContext context = identity.Impersonate(); 

No olvides deshacer el contexto suplantado cuando hayas terminado.