113 votes

Comment démarrer un processus en mode administrateur en C#

J'ai un projet d'application Visual Studio Windows. J'ai ajouté du code pour télécharger un fichier de mise à jour de l'installateur. Une fois le téléchargement terminé, l'installateur doit disposer des privilèges d'administrateur pour s'exécuter. J'ai ajouté un fichier manifeste.

Lorsque l'utilisateur clique sur le DownloadUpdate.exe, l'UAC lui demande des autorisations d'administrateur. J'ai donc supposé que tous les processus créés et appelés dans DownloadUpdate.exe s'exécuteront en tant qu'administrateur. J'ai donc fait en sorte que l'installation appelle mon fichier téléchargé avec le code suivant :

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 votes

Non, vous ne pouvez pas supposer que tous les processus exécutés par DownloadUpdater.exe le sont en mode administrateur. En fait, ce serait une terrible violation de la sécurité. Si vous exécutez un autre processus qui nécessite des droits d'administrateur, l'utilisateur sera à nouveau invité.

90voto

Nick Craver Points 313913

Essayez ça :

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

Alternativement, adoptez la voie du manifeste pour votre application .

9 votes

Notez que cette réponse ne fonctionnera probablement pas sans p.StartInfo.UseShellExecute = true; .

57voto

drgmak Points 514

Tout d'abord, vous devez inclure dans votre projet

using System.Diagnostics;

Après cela, vous pourriez écrire une méthode générale que vous pourriez utiliser pour les différents fichiers .exe que vous souhaitez utiliser. Ce serait comme ci-dessous :

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

Si vous voulez par exemple exécuter notepad.exe, il vous suffit d'appeler cette méthode :

ExecuteAsAdmin("notepad.exe");

27voto

MSajjadi Points 851

C'est une réponse claire à votre question : Comment puis-je forcer mon application .NET à s'exécuter en tant qu'administrateur ?

Résumé :

Clic droit sur le projet -> Ajouter un nouvel élément -> Fichier de manifeste d'application

Ensuite, dans ce fichier, changez une ligne comme ceci :

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

Compilez et exécutez !

2 votes

Comme vous le voyez, cette ligne est incluse dans la réponse de @Hans Passant. Mais est-ce que seule cette ligne ouvrira la fenêtre de l'UAC à chaque fois que le programme lancera un autre programme ?

0 votes

Cela fonctionne parfaitement pour moi, merci

23voto

Darin Dimitrov Points 528142
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, "");

Fonctionne également avec ProcessStartInfo :

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

5 votes

Ok, mais pourquoi utiliser AppendChar ? Ne pouvez-vous pas écrire pass="secret" ?

30 votes

C'était un secret.

7 votes

@Jet non, car il faut une securestring et non une chaîne de caractères, et ces dernières ne sont jamais destinées à être disponibles sous forme d'un morceau non crypté en mémoire.

18voto

Hans Passant Points 475940

Cela fonctionne lorsque je l'essaie. J'ai vérifié à l'aide de deux exemples de programmes :

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

J'ai d'abord vérifié que je reçois la bombe UAC :

System.UnauthorizedAccessException : L'accès au chemin 'c : \program fichiers \test.txt est refusé.
// etc.

Puis j'ai ajouté un manifeste à ConsoleApplication1 avec la phrase :

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

Pas de bombe. Et un fichier que je ne peux pas supprimer facilement :) Ceci est cohérent avec plusieurs tests précédents sur diverses machines sous Vista et Win7. Le programme lancé hérite du jeton de sécurité du programme de démarrage. Si le programme de démarrage a acquis des privilèges d'administrateur, le programme lancé les a également.

0 votes

Impossible de supprimer ? Veuillez élaborer, cela me semble familier.

0 votes

@ArlenBeiler : il veut probablement parler d'un manifeste intégré à l'application ou d'un fichier .exe.manifest sur le disque à côté de l'exécutable.

0 votes

@ThomasW. Je pense qu'il fait référence au fichier de test qui nécessite des autorisations d'administrateur pour être supprimé. J'ai rencontré ce problème à plusieurs reprises et il faut généralement aller dans l'onglet sécurité et modifier certains paramètres, si je me souviens bien. Je pense que j'ai fini par trouver un moyen. L'invite de commande élevée peut également fonctionner, mais soyez prudent. Le temps apporte parfois des réponses :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X