2008-09-25 6 views
114

J'essaye d'installer un service using InstallUtil.exe mais invoqué par Process.Start. Voici le code:Elevating privilege de processus par programme?

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

m_strInstallUtil est le chemin complet et exe « InstallUtil.exe » et strExePath est le chemin complet/nom à mon service. L'exécution de la syntaxe de ligne de commande à partir d'une invite de commande élevée fonctionne;

en cours d'exécution à partir de mon application (en utilisant le code ci-dessus) ne fonctionne pas. Je suppose que je suis confronté à un problème d'élévation de processus, alors comment exécuter mon processus dans un état élevé? Ai-je besoin de regarder ShellExecute pour cela?

Tout est sous Windows Vista. Je cours le processus dans le débogueur VS2008 élevé au privilège d'admin.

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

Répondre

138

Vous pouvez indiquer le nouveau processus doit être démarré avec des autorisations élevées en définissant la propriété Verbe de votre objet startInfo à « runas », comme suit:

startInfo.Verb = "runas"; 

Cela entraînera de Windows de se comporter comme si le processus a été démarré depuis Explorer avec la commande de menu "Exécuter en tant qu'administrateur". Cela signifie que l'invite UAC apparaîtra et devra être reconnue par l'utilisateur: si cela n'est pas souhaitable (par exemple parce que cela arriverait au milieu d'un long processus), vous devrez exécuter votre processus d'hôte complet avec des autorisations élevées par Create and Embed an Application Manifest (UAC) pour exiger le niveau d'exécution 'HighestAvailable': l'invite UAC apparaît dès le démarrage de votre application et entraîne l'exécution de tous les processus enfants avec des autorisations élevées sans invite supplémentaire. Editer: Je vois que vous venez d'éditer votre question pour indiquer que "runas" n'a pas fonctionné pour vous. C'est vraiment étrange, comme il se doit (et ça marche 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.

+6

"runas" n'a pas fonctionné pour moi non plus. Peut-être que cela fonctionne seulement avec UAC éteint? –

+0

Cela m'a aidé, je me demande si cela fonctionne pour tous les systèmes d'exploitation Windows? –

+1

Cela ne semble pas fonctionner sur Windows 8. Fonctionne correctement sur les versions précédentes. – Despertar

1

Vous devez utiliser Usurpation d'identité pour élever l'état. N'oubliez pas d'annuler le contexte usurpé lorsque vous avez terminé.

+21

Vous n'avez pas dit comment obtenir l'accessToken. LogonUser fournira le contexte de sécurité restreint d'un utilisateur lorsque l'UAC est activé. – cwa

19

Selon this article, seul ShellExecute vérifie le manifeste incorporé et invite l'utilisateur à l'élévation si nécessaire, contrairement à CreateProcess et aux autres API. J'espère que cela aide.

+1

Merci, c'était la seule façon de le faire fonctionner. –

+2

le lien n'est pas disponible maintenant –

+0

@ M.Kumaran si vous voyez des liens morts s'il vous plaît les modifier en utilisant https://web.archive.org –

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

Ceci le fera sans UAC - pas besoin de démarrer un nouveau processus. Si l'utilisateur en cours est membre du groupe Admin comme pour mon cas.

+0

En utilisant ce code, je reçois une erreur d'autorisation: "Demande d'autorisation de l'entité de sécurité a échoué.":( – Leonardo

+0

Peut-être" Si l'utilisateur est en cours administrateur "* – hB0

+1

intéressant - cela peut aller sur n'importe quelle méthode, pas seulement une méthode d'action (j'ai même essayé sur la méthode définie dans une page ASPX) –

34

Ce code met ci-dessus tout et redémarre l'application actuelle WPF avec administration 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: L'application manière manifeste est préférée:

projet Clic droit dans visuel studio, ajouter, nouveau fichier manifeste d'application, modifiez le fichier afin que vous ayez requireAdministrator comme indiqué ci-dessus.

Un problème avec la façon originale: Si vous mettez le code de redémarrage dans App.xaml.cs OnStartup, il peut encore démarrer brièvement la fenêtre principale même si Shutdown a été appelé. Ma fenêtre principale a explosé si init.xaml.cs init n'était pas exécuté et dans certaines conditions de course, il le ferait.

+0

Voir ci-dessous pour des améliorations. – JCCyC

+0

requireAdministrator ne fonctionnait pas dans mon cas, donc je devais le faire à votre guise, cela a résolu mon problème, merci, mais j'ai dû mettre l'application Single Instance à false. – chris

Questions connexes