Comment forcer mon application .NET à s'exécuter en tant qu'administrateur?

876

Une fois mon programme installé sur une machine cliente, comment puis-je forcer mon programme à s'exécuter en tant qu'administrateur sur Windows 7?

Or
la source
3
Outre ce que Binary Worrier a écrit, vous voudrez peut-être écrire du code pour tester si vous avez des privilèges d'administrateur .. (c'est ce que vous demandez?)
lexu
39
Cependant, je ne prendrais pas cette tâche à la légère, vous devriez vérifier ce dont elle a réellement besoin pour l'administration et voir si vous pouvez contourner cela. Aucun client ne sera heureux d'exécuter une application en mode administrateur à tout moment. Beaucoup de gros clients n'envisageront même pas une application comme celle-ci, et si le test du logo vous importe, cela ne passera pas comme ça.
Alex
2
Alex est vraiment sur le point. Si possible, n'augmentez que lorsque cela est nécessaire, sinon, la stratégie de groupe, l'UAC et un certain nombre d'autres variables entrent en jeu. À tout le moins, avec l'UAC, l'utilisateur devrait autoriser à chaque exécution plutôt que seulement lorsqu'une action utilisateur spécifique est effectuée.
Anthony Mason
La bonne façon consiste à intégrer un fichier manifeste dans votre application.
Elmue

Réponses:

1145

Vous voudrez modifier le manifeste qui est incorporé dans le programme. Cela fonctionne sur Visual Studio 2008 et supérieur: Projet + Ajouter un nouvel élément, sélectionnez "Fichier manifeste d'application". Remplacez l' <requestedExecutionLevel>élément par:

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

L'utilisateur reçoit l' invite UAC lorsqu'il démarre le programme. Utilisez judicieusement; leur patience peut s'user rapidement.

Hans Passant
la source
33
Si vous obtenez une erreur ClickOnce lorsque vous essayez de compiler, consultez cette réponse: stackoverflow.com/questions/11023998/…
SSS
17
Votre projet doit être configuré pour utiliser également le manifeste de l'application - dans les propriétés du projet, vérifiez l'onglet "Application" et assurez-vous que le "Manifest:" sous "Ressources" est défini sur votre app.manifest (ou tout ce que vous avez nommé. fichier manifeste)
Victor Chelaru
7
J'ai dû recharger le projet avant que VS ne m'invite à redémarrer en mode administrateur.
Jon
3
@Alejandro - Oui, l'UAC peut être désactivé, mais dans ce cas, l'application s'exécutera automatiquement en tant qu'administrateur (en supposant que votre utilisateur dispose de privilèges d'administrateur), car la désactivation de l'UAC signifie que tout s'exécute avec le privilège le plus élevé autorisé à l'utilisateur. C'est un peu comme se plaindre que si vous installez une serrure de fantaisie sur la porte, cela ne fonctionnera pas si la porte est retirée.
Erik Funkenbusch
4
@ErikFunkenbusch Il ne "s'exécutera pas automatiquement en tant qu'administrateur", il s'exécutera sous les autorisations normales de l'utilisateur (admin si l'utilisateur est admin, ou standard si l'utilisateur est standard). S'appuyer sur ce cas particulier, même s'il s'agit de la valeur par défaut, est ce que les bons programmes éviteront comme la peste. Suite à votre analogie, la serrure de fantaisie est agréable et tout, mais un logiciel correctement conçu doit prévoir le cas où la porte entière est retirée, même si c'est un événement rare.
Alejandro
155

L'ajout d'un requestedExecutionLevelélément à votre manifeste ne représente que la moitié de la bataille; vous devez vous rappeler que l' UAC peut être désactivé. Si c'est le cas, vous devez effectuer la vérification à l'ancienne et mettre en place une boîte de dialogue d'erreur si l'utilisateur n'est pas administrateur
( IsInRole(WindowsBuiltInRole.Administrator)faites appel à votre thread CurrentPrincipal).

Anders
la source
22
Vous pouvez également utiliser <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> également
Mark Kram
18
@MarkKram: Qu'est-ce que le plus élevé disponible a à voir avec cela? La question concerne le forçage de l'administrateur, le plus élevé disponible est moins restrictif que requireAdministrator et permettra à un utilisateur non administrateur de démarrer l'application sans élévation sans invite UAC, seuls les administrateurs seront invités ...
Anders
3
Voici un exemple MSDN deIsInRole , Anders en parle.
Uwe Keim
Je ne me souviens plus des détails exacts, mais je pense que cela dépend de ce que vous entendez par désactivé. Placer le "curseur UAC" jusqu'en bas n'est pas la même chose que désactiver l'UAC (sauf sur Vista). Si l'UAC est complètement désactivé, tout le mécanisme du niveau d'intégrité est désactivé et seule la fonctionnalité runas.exe classique de 2000 / XP est disponible. La vérification du rôle d'administrateur gère le cas runas.exe.
Anders
1
J'ai défini EnableLUA sur 0 sur le serveur 2008 R2 et me suis retiré du groupe Administrateurs, redémarré et maintenant un exe qui spécifie level = "requireAdministrator" s'exécute sans aucune invite
Tal Aloni
87

Les étapes détaillées sont les suivantes.

  1. Ajouter un fichier manifeste d'application à la solution
  2. Changer le paramètre d'application en "app.manifest"
  3. Mettre à jour la balise de "requiredExecutionLevel" pour exigerAdministrateur.

Ajout de fichier dans la solution

Sélectionner le fichier manifeste d'application

Sélectionnez l'option manifeste

Mettre à jour le fichier manifeste

Notez que l'utilisation de ce code vous devez désactiver les paramètres de sécurité de ClickOnce, pour ce faire, allez dans Propriétés -> Sécurité -> Sécurité ClickOnce

Hassan Rahman
la source
New Item...n'est pas une option sur mon projet de service d'installation. Comment pourrais-je ajouter le manifeste de l'application? Je peux l'ajouter à mon projet principal mais pas à son installateur.
HackSlash
61

J'ai implémenté du code pour le faire manuellement:

using System.Security.Principal;
public bool IsUserAdministrator()
{
    bool isAdmin;
    try
    {
        WindowsIdentity user = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(user);
        isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch (UnauthorizedAccessException ex)
    {
        isAdmin = false;
    }
    catch (Exception ex)
    {
        isAdmin = false;
    }
    return isAdmin;
}
NG.
la source
45
Cela ne détecte que si le contexte s'exécute en tant qu'administrateur, il n'empêche pas l'application de s'exécuter en tant qu'administrateur comme demandé par l'OP
Matt Wilko
5
Je ne pense pas qu'il existe un moyen programmatique de forcer une application à élever ses propres perms. S'il y en avait, ce serait tout à fait le risque pour la sécurité, non?
Mark Richman
6
Bien que votre solution soit bonne mais la question était différente. ;)
Yash
voir une version refactorisée de cette méthode ici stackoverflow.com/a/50186997 (subjective)
Hakan Fıstık
Cela ne répond pas à la question!
Elmue
19

Tout en travaillant sur Visual Studio 2008, faites un clic droit sur Project -> Add New Itempuis choisissez Application Manifest File.

Dans le fichier manifeste, vous trouverez la balise requestedExecutionLevelet vous pouvez définir le niveau sur trois valeurs:

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

OU

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

OU

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

Pour configurer votre application pour qu'elle s'exécute en tant qu'administrateur, vous devez choisir celle du milieu.

Rashad Maqsood
la source
Cela marche. Cependant, il a fait apparaître une fenêtre cmd vide lors de l'exécution de l'application CMD (en utilisant l'application c # cmd pour exécuter un exe en arrière-plan).
WM
13

Selon

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

vous voudrez ajouter un manifeste d'application si vous n'en avez pas déjà un ou si vous ne savez pas comment en ajouter un. Comme certains projets n'ajoutent pas automatiquement un fichier manifeste distinct, accédez d'abord aux propriétés du projet, accédez à l' onglet Application et vérifiez que votre projet n'exclut pas le manifeste au bas du robinet.

  • Ensuite, faites un clic droit sur le projet
  • Ajouter un nouvel élément
  • Enfin, recherchez et cliquez sur Fichier manifeste d'application
Justin Mcconnell
la source
12

Dans Visual Studio 2010, cliquez avec le bouton droit sur le nom de votre projet. Appuyez sur "Afficher les paramètres Windows", cela génère et ouvre un fichier appelé "app.manifest". Dans ce fichier, remplacez "asInvoker" par "requireAdministrator" comme expliqué dans les sections commentées du fichier.

Évolué
la source
6
Cette réponse concerne VB.NET :-), pas VS 2010 en général. Les réponses «Ajouter un nouvel élément» concernent C #. En C ++, vous pouvez le faire dans les paramètres du projet.
Philm
12

Une autre façon de le faire, en code uniquement, consiste à détecter si le processus s'exécute en tant qu'administrateur comme dans la réponse de @NG. . Et puis ouvrez à nouveau l'application et fermez celle en cours.

J'utilise ce code lorsqu'une application n'a besoin que de privilèges d'administrateur lorsqu'elle est exécutée dans certaines conditions, comme lors de l'installation elle-même en tant que service. Il n'a donc pas besoin d'être exécuté en tant qu'administrateur tout le temps comme les autres réponses le forcent également.

Remarque dans le code ci-dessous NeedsToRunAsAdminest une méthode qui détecte si dans les conditions actuelles des privilèges d'administrateur sont requis. Si cela retourne, falsele code ne s'élèvera pas. C'est un avantage majeur de cette approche par rapport aux autres.

Bien que ce code présente les avantages mentionnés ci-dessus, il a besoin de se relancer en tant que nouveau processus qui n'est pas toujours ce que vous voulez.

private static void Main(string[] args)
{
    if (NeedsToRunAsAdmin() && !IsRunAsAdmin())
    {
        ProcessStartInfo proc = new ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = Environment.CurrentDirectory;
        proc.FileName = Assembly.GetEntryAssembly().CodeBase;

        foreach (string arg in args)
        {
            proc.Arguments += String.Format("\"{0}\" ", arg);
        }

        proc.Verb = "runas";

        try
        {
            Process.Start(proc);
        }
        catch
        {
            Console.WriteLine("This application requires elevated credentials in order to operate correctly!");
        }
    }
    else
    {
        //Normal program logic...
    }
}

private static bool IsRunAsAdmin()
{
    WindowsIdentity id = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(id);

    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
TheLethalCoder
la source
1
+1 pour l'approche en code uniquement. Notez que vous devez activer l'UAC pour avoir la possibilité de lancer quoi que ce soit avec en runastant qu'administrateur à partir d'un utilisateur non administrateur, sinon il s'ouvrira silencieusement avec les autorisations utilisateur actuelles (vérifié sur Windows 7 64 bits). Pour autant que je sache, la seule chose que vous pouvez faire avec l'UAC désactivé et le droit d'administrateur manquant est d'arrêter l'exécution au bon moment.
reallynice
9

Vous pouvez créer le manifeste à l'aide des paramètres de sécurité ClickOnce, puis le désactiver:

Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings

Après avoir cliqué dessus, un fichier sera créé sous le dossier des propriétés du projet appelé app.manifest une fois celui-ci créé, vous pouvez décocher l' Enable ClickOnce Security Settingsoption

Ouvrez ce fichier et changez cette ligne:

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

à:

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

Cela rendra le programme nécessitera des privilèges d'administrateur.

Yochai Timmer
la source
7

Ceci est une version simplifiée de cette réponse , ci-dessus par @NG

public bool IsUserAdministrator()
{
    try
    {
        WindowsIdentity user = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(user);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch
    {
        return false;
    }
}
Hakan Fıstık
la source
1
Cela ne répond pas à la question!
Elmue
@Elmue, il est plus logique d'ajouter votre commentaire à la réponse originale que je viens de refactoriser, vous pouvez trouver un lien vers cette réponse dans la mienne.
Hakan Fıstık
-3

Cliquez avec le bouton droit sur votre exécutable, accédez à Propriétés> Compatibilité et cochez la case «Exécuter ce programme en tant qu'administrateur».

Si vous souhaitez l'exécuter en tant qu'administrateur pour tous les utilisateurs, faites la même chose dans «Modifier les paramètres pour tous les utilisateurs».

SlickJayD
la source
4
Cela ne répond pas à la question. "Une fois mon programme installé sur une machine cliente", pas "comment faire".
Joe
Désolé d'être flou. Une fois votre programme installé, modifiez ce paramètre dans les propriétés de votre exécutable (votre programme principal, pas le programme d'installation). Il veut forcer son programme à s'exécuter en tant qu'administrateur.
SlickJayD
2
Il vaut mieux définir l'exigence d'administration dans le manifeste. Je dirais que cela répond à la question, mais à peine.
BradleyDotNET
3
@Joe Pour être honnête, la réponse acceptée ne répond pas à la question OP car vous oblige à réinstaller l'application exe. Ce n'est guère une solution pour "Une fois mon programme installé". Si quoi que ce soit, cette réponse décotée est plus correcte que la réponse acceptée, donc je ne comprends pas pourquoi cette réponse a plus de 400 votes.
NickG
En fait, il répond parfaitement aux deux questions. Il n'y a pas beaucoup de chances de changer le manifeste une fois installé et les programmes ne devraient pas essayer d'élever leurs autorisations une fois exécutés - dans de nombreux environnements - c'est un bon chemin pour être appelé malware. Dans la plupart des entreprises - cette réponse est la meilleure car elle met la responsabilité sur l'utilisateur et ses autorisations. J'écris beaucoup de code que je ne peux ni "voir" ni exécuter une fois qu'il est en production. Essayez de ne pas être plus intelligent que vos propres préoccupations en matière de sécurité.
jinzai