2010-03-28 50 views
63

Tengo un proyecto de aplicación de Visual Studio para Windows. He agregado código para descargar un archivo de actualización del instalador. El instalador después de que haya finalizado la descarga necesitaría privilegios de administrador para ejecutarse. He agregado un archivo de manifiesto.Cómo iniciar un proceso como modo de administrador en C#

Cuando el usuario hace clic en DownloadUpdate.exe, UAC solicita al usuario los permisos de administrador. Así que asumí que todos los procesos creados y llamados dentro de DownloadUpdate.exe se ejecutarán en la capacidad de administración. Así que hice el establecimiento de llamada a mi archivo descargado con el siguiente código:

Process p = new Process(); 
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
p.StartInfo.FileName = strFile; 
p.StartInfo.UseShellExecute = false; 
p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.RedirectStandardError = true; 
+1

No, no puede suponer que todos los procesos ejecutados desde DownloadUpdater.exe se ejecutan en modo de administrador. De hecho, eso sería una terrible brecha de seguridad. Si ejecuta otro proceso que necesita derechos de administrador, se volverá a solicitar al usuario. –

Respuesta

63

Prueba esto:

//Vista or higher check 
if (System.Environment.OSVersion.Version.Major >= 6) 
{ 
    p.StartInfo.Verb = "runas"; 
} 

Alternativamente, go the manifest route for your application.

+0

¡Es trabajo para mí! –

13
var pass = new SecureString(); 
pass.AppendChar('s'); 
pass.AppendChar('e'); 
pass.AppendChar('c'); 
pass.AppendChar('r'); 
pass.AppendChar('e'); 
pass.AppendChar('t'); 
Process.Start("notepad", "admin", pass, ""); 

Works también con ProcessStartInfo:

var psi = new ProcessStartInfo 
{ 
    FileName = "notepad", 
    UserName = "admin", 
    Domain = "", 
    Password = pass, 
    UseShellExecute = false, 
    RedirectStandardOutput = true, 
    RedirectStandardError = true 
}; 
Process.Start(psi); 
+3

Ok, pero ¿por qué usas AppendChar? ¿No puedes escribir 'pass =" secret "'? – Jet

+13

Cauz era un secreto – Sayka

+5

@Jet no, ya que no necesita una cadena de seguridad ni una cadena y estos nunca deben estar disponibles como 1 fragmento no encriptado en la memoria –

17

Esto funciona cuando lo intento. Verifiqué con dos programas de ejemplo:

using System; 
using System.Diagnostics; 

namespace ConsoleApplication1 { 
    class Program { 
    static void Main(string[] args) { 
     Process.Start("ConsoleApplication2.exe"); 
    } 
    } 
} 

using System; 
using System.IO; 

namespace ConsoleApplication2 { 
    class Program { 
    static void Main(string[] args) { 
     try { 
     File.WriteAllText(@"c:\program files\test.txt", "hello world"); 
     } 
     catch (Exception ex) { 
     Console.WriteLine(ex.ToString()); 
     Console.ReadLine(); 
     } 
    } 
    } 
} 

Primero verifica que consigo la bomba UAC:

System.UnauthorizedAccessException: acceso a la ruta 'C: \ programa files \ test.txt 'denegado.
// etc ..

Luego añade un manifiesto a ConsoleApplication1 con la frase:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 

Ninguna bomba. Y un archivo que no puedo borrar fácilmente :) Esto es consistente con varias pruebas previas en varias máquinas con Vista y Win7. El programa iniciado hereda el token de seguridad del programa de inicio. Si el juez de salida ha adquirido privilegios de administrador, el programa iniciado también los tiene.

+0

No se puede eliminar? Por favor, elabore, esto suena familiar. –

+0

¡Muchas gracias! Me ayudó mucho. Obtenga +1 – Jet

+0

@ArlenBeiler: probablemente se refiera a un manifiesto incrustado en la aplicación frente a un archivo .exe.manifest en el disco, lado a lado, del ejecutable. –

15

Ésta es una clara respuesta a su pregunta: How do I force my .NET application to run as administrator?

Resumen:

Haga clic derecho en el proyecto -> Agregar nuevo elemento -> Solicitud de archivo de manifiesto

Luego, en ese archivo de cambiar una línea como este:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 

Compilar y ejecutar!

+1

Como ve, esa línea está incluida en la respuesta de @Hans Passant. ¿Pero solo esa línea abrirá la ventana de UAC cada vez que el programa inicie otros programas? – Jet

0

Probablemente necesite configurar su aplicación como una aplicación x64.

El complemento de IIS funciona solo en 64 bits y no funciona en 32 bits, y un proceso generado a partir de una aplicación de 32 bits parece funcionar como un proceso de 32 bits, y lo mismo ocurre con las aplicaciones de 64 bits.

Mira: Start process as 64 bit

4

Aquí está un ejemplo de proceso de ejecución como administrador sin ventanas del símbolo

Process p = new Process(); 
    p.StartInfo.FileName = Server.MapPath("process.exe"); 
    p.StartInfo.Arguments = ""; 
    p.StartInfo.UseShellExecute = false; 
    p.StartInfo.CreateNoWindow = true; 
    p.StartInfo.RedirectStandardOutput = true; 
    p.StartInfo.Verb = "runas"; 
    p.Start(); 
    p.WaitForExit(); 
+0

¡Esto resolvió mi problema! El mensaje surgiría de las respuestas de los demás. La combinación de UseShellExecute, CreateNoWindow y RedirectStandardOutput detuvo eso para mí. –

+0

Esto no se ejecuta como administrador. Si agrega un manifiesto y solicita permisos elevados, aún no funcionará. – MtnManChris

13

En primer lugar es necesario incluir en su proyecto

using System.Diagnostics; 

Después de eso podría escribir un método general que podría usar para diferentes archivos .exe que quiera usar. Sería como a continuación:

public void ExecuteAsAdmin(string fileName) 
     { 
      Process proc = new Process(); 
      proc.StartInfo.FileName = fileName; 
      proc.StartInfo.UseShellExecute = true; 
      proc.StartInfo.Verb = "runas"; 
      proc.Start(); 
     } 

Si desea ejecutar, por ejemplo, notepad.exe entonces todo lo que hace es que llama a este método:

ExecuteAsAdmin("notepad.exe"); 
0

El uso de este método:

public static int RunProcessAsAdmin(string exeName, string parameters) 
    { 
     try { 
      System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 
      startInfo.UseShellExecute = true; 
      startInfo.WorkingDirectory = CurrentDirectory; 
      startInfo.FileName = Path.Combine(CurrentDirectory, exeName); 
      startInfo.Verb = "runas"; 
      //MLHIDE 
      startInfo.Arguments = parameters; 
      startInfo.ErrorDialog = true; 

      Process process = System.Diagnostics.Process.Start(startInfo); 
      process.WaitForExit(); 
      return process.ExitCode; 
     } catch (Win32Exception ex) { 
      WriteLog(ex); 
      switch (ex.NativeErrorCode) { 
       case 1223: 
        return ex.NativeErrorCode; 
       default: 
        return ErrorReturnInteger; 
      } 

     } catch (Exception ex) { 
      WriteLog(ex); 
      return ErrorReturnInteger; 
     } 
    } 

Espero que ayude.

0
Process proc = new Process();                
        ProcessStartInfo info = 
        new ProcessStartInfo("Your Process name".exe, "Arguments"); 
        info.WindowStyle = ProcessWindowStyle.Hidden; 
        info.UseShellExecute =true; 
        info.Verb ="runas"; 
        proc.StartInfo = info; 
        proc.Start(); 
+0

"Argumentos" no son obligatorios en ProcessStartInfo, solo el nombre del proceso es suficiente para iniciar el proceso. –

Cuestiones relacionadas