L'élévation de processus de privilège par programmation?

J'essaie d'installer un service en utilisant InstallUtil.exe mais invoqué via Process.Start. Voici le code:

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

Où {[2] } est le chemin complet et exe à " InstallUtil.exe " et {[3] } est le chemin/nom complet de mon service.

L'exécution de la syntaxe de ligne de commande à partir d'une invite de commande élevée fonctionne; l'exécution à partir de mon application (en utilisant le code ci-dessus) ne fonctionne pas. Je suppose que je fais face à un problème d'élévation de processus, alors comment pourrais-je exécuter mon processus dans un état élevé? Faire Je dois regarder ShellExecute pour cela?

Tout cela est sous Windows Vista. J'exécute le processus dans le débogueur VS2008 élevé au privilège admin.

J'ai aussi essayé de définir startInfo.Verb = "runas"; mais cela n'a pas semblé résoudre le problème.

125
demandé sur Cœur 2008-09-25 17:38:00

5 réponses

Vous pouvez indiquer que le nouveau processus doit être démarré avec des autorisations élevées en définissant la propriété Verb de votre objet startInfo sur 'runas', comme suit:

startInfo.Verb = "runas";

Cela entraînera Windows à se comporter comme si le processus a été démarré à partir de L'Explorateur avec la commande de menu "Exécuter en tant Qu'administrateur".

Cela signifie que l'invite UAC va venir et devra être validé par l'utilisateur: si ce n'est pas souhaitable (par exemple parce qu'elle arriverait au milieu d'une longue processus), vous devrez exécuter l'ensemble de votre processus hôte avec des autorisations élevées en Créer et intégrer un manifeste D'Application (UAC) pour exiger le niveau d'exécution 'highestAvailable': cela fera apparaître l'invite UAC dès que votre application est démarrée, et fera fonctionner tous les processus enfants avec des autorisations élevées sans invite supplémentaire.

Edit: je vois que vous venez d'éditer votre question pour indiquer que "runas" ne fonctionnait pas pour vous. C'est vraiment étrange, comme il se doit (et ne pour moi dans plusieurs applications de production). Exiger que le processus parent s'exécute avec des droits élevés en intégrant le manifeste devrait certainement fonctionner, cependant.

155
répondu mdb 2016-02-04 09:37:34

CE code rassemble tout ce qui précède et redémarre l'application WPF actuelle avec admin privs:

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)

Mise à jour: la manière manifeste de l'application est préférée:

Faites un clic droit sur le projet dans visual studio, ajoutez, nouveau fichier manifeste d'application, modifiez le fichier pour que vous ayez défini requireAdministrator comme indiqué ci-dessus.

Un problème avec la manière originale: si vous mettez le code de redémarrage dans l'application.XAML.cs OnStartup, il peut encore démarrer la fenêtre principale brièvement même si L'arrêt était appelé. Ma fenêtre principale a explosé si l'application.XAML.cs init n'a pas été exécuté et dans certaines conditions de course, il le ferait.

36
répondu Curtis Yallop 2012-08-14 21:13:59

Selon Cet article , seul ShellExecute vérifie le manifeste intégré et invite l'utilisateur à l'élévation si nécessaire, alors que CreateProcess et d'autres API ne le font pas. J'espère que cela aide.

19
répondu Jeremy Thompson 2017-03-16 03:53:50
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

Cela le fera sans UAC-pas besoin de commencer un nouveau processus. Si l'utilisateur est membre du groupe Admin comme pour mon cas.

6
répondu hB0 2012-10-03 15:19:53

Vous devez utiliser L'usurpation d'identité pour élever l'état.

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

N'oubliez pas d'annuler le contexte usurpé lorsque vous avez terminé.

2
répondu Vijesh VP 2010-12-21 12:33:13