2008-09-25 17 views
114

Estoy tratando de instalar un servicio usando InstallUtil.exe pero invocado a través de Process.Start. Aquí está el código:¿Aumenta el privilegio del proceso programáticamente?

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

donde m_strInstallUtil es la ruta completa y el exe para "InstallUtil.exe" y strExePath es la ruta completa/nombre a mi servicio.

Ejecutar la sintaxis de la línea de comando desde un símbolo de sistema elevado funciona; 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? ¿Tengo que mirar 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.

Respuesta

138

Puede indicar el nuevo proceso debe iniciarse con permisos elevados mediante el establecimiento de la propiedad verbo de su objeto startInfo a 'runa', de la siguiente manera:

startInfo.Verb = "runas"; 

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

Esto significa que el aviso de UAC aparecerá y deberá ser confirmado por el usuario: si esto no es deseable (por ejemplo, porque ocurriría en medio de un proceso prolongado), deberá ejecutar su todo el proceso de host con permisos elevados por Create and Embed an Application Manifest (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 indicaciones 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.

+6

"runas" tampoco funcionó para mí. ¿Podría ser que solo funciona con UAC desactivado? –

+0

Me ayudó, me pregunto si esto funciona para todos los SO de Windows. –

+1

Esto no parece funcionar en Windows 8. Funcionó bien en versiones anteriores. – Despertar

1

Debe 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.

+21

No ha dicho cómo obtener el accessToken. LogonUser proporcionará un contexto de seguridad restringido para el usuario cuando UAC esté habilitado. – cwa

19

Según this article, solo ShellExecute comprueba el manifiesto incrustado y solicita al usuario elevación si es necesario, mientras que CreateProcess y otras API no lo hacen. Espero eso ayude.

+1

Gracias, esta fue la única forma en que lo hice funcionar. –

+2

el enlace no está disponible ahora –

+0

@ M.Kumaran si ve enlaces muertos, edítelos usando https://web.archive.org –

5
[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.

+0

Utilizando este código, obtengo un error de permiso: "Falló la solicitud de permiso de la entidad de seguridad.":( – Leonardo

+0

Quizás" Si el usuario en ejecución es miembro de Admin "* – hB0

+1

interesante - esto puede seguir cualquier método, no solo un método de acción (incluso lo probé en el método definido en una página ASPX) –

34

Este código pone lo anterior todos juntos y se reinicia la aplicación actual WPF con privs de administración:

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 el modo manifiesto de la aplicación: Proyecto clic derecho

en Visual Studio, agregar, nuevo archivo de manifiesto de la aplicación, cambie el archivo para que tenga requiredAdministrator establecido como se muestra en la imagen anterior.

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

+0

Vea a continuación las mejoras. – JCCyC

+0

requireAdministrator no funcionó en mi caso. Así que tuve que hacerlo a tu manera. ¡Esto resolvió mi problema! Gracias. Pero tuve que configurar la aplicación de instancia única en falso. – chris

Cuestiones relacionadas