7 votes

Accorder des privilèges d'administrateur à une application lancée au démarrage sans invite UAC?

Contexte

J'ai écrit une petite application C#/.NET 4.0 qui synchronise divers paramètres d'un jeu installé dans Program Files vers d'autres copies du même jeu sur différentes machines (pensez à la synchronisation des favoris de Chrome, mais pour ce jeu). La synchronisation en elle-même est une affaire relativement simple, traitant des fichiers stockés à l'intérieur du dossier Program Files du jeu.

Sur ma machine, cela fonctionne bien sans avoir à élever mon application via UAC. Windows 7 fait utiliser la virtualisation de Program Files pour le jeu et mon application fonctionne bien avec cela.

Cependant, sur beaucoup de machines de testeurs, je reçois des rapports indiquant que l'application ne peut pas fonctionner avec les fichiers et dans certains cas, elle ne peut même pas voir le dossier du jeu ! Demander à l'utilisateur de cliquer avec le bouton droit et de "Exécuter en tant qu'administrateur" résout le problème dans tous les cas.

Donc, il suffit de définir le manifeste de l'application pour exiger des privilèges d'administrateur, n'est-ce pas ? C'est bien (bien que pas idéal) lorsque l'utilisateur invoque manuellement l'application ou le processus de synchronisation car ils interagiront avec l'application et seront prêts à accepter une demande UAC.

Cependant, l'une des fonctionnalités de mon application est une option "Synchroniser automatiquement", qui permet à l'utilisateur de "configurer et oublier" l'application. Avec cette option activée, l'application se place dans le registre à HKCU\Software\Microsoft\Windows\CurrentVersion\Run pour être exécutée au démarrage et se place dans la barre d'état système pour synchroniser les paramètres en arrière-plan au besoin.

De toute évidence, je dois être plus intelligent ici. Présenter une invite UAC dès que l'utilisateur se connecte à son compte ou à des intervalles aléatoires par la suite n'est pas la voie à suivre.

Donc, ma question !

Quelle est la meilleure façon d'aborder une situation où j'aurais besoin d'exécuter une application au démarrage nécessitant des privilèges d'administrateur ? Existe-t-il un moyen de faire autoriser à l'utilisateur une installation qui fait que le système exécute automatiquement l'application avec les bons privilèges sans demande au démarrage/connexion ?

Mise à jour Juste pour être clair, cela doit être réalisable en code.

6voto

Vous devriez envisager de rendre votre fonctionnalité de synchronisation existante dans un service Windows. C'est la méthode préférée pour exécuter une fonctionnalité en 'arrière-plan' sur Windows.

Le service peut soit s'exécuter sous le compte de l'utilisateur (en supposant qu'il a les autorisations pour modifier les fichiers), soit vous pouvez utiliser un autre compte qui le peut. Dans le pire des cas, vous pouvez exécuter en tant que SYSTEM (bien que ce ne soit pas la meilleure pratique).

Si vous avez déjà fonctionnalité votre processus en arrière-plan, alors ce devrait être un processus simple à convertir en un Service.

Il y a un projet d'exemple ici qui vous mettra sur la bonne voie: http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx

2voto

Kate Gregory Points 13451

Depuis que vous avez mentionné le démarrage au lancement, pourquoi ne pas utiliser une tâche planifiée au lieu de ce que vous faites avec le registre ? Vous pouvez les configurer à partir du code - il y a un projet sur CodePlex qui est essentiellement un wrapper géré pour vous éviter de devoir faire les PInvokes vous-même. Vous exécutez votre petite application "configurer la tâche de démarrage" en mode élevé, et il spécifie que l'application doit être lancée en mode élevé, et l'utilisateur ne sera même pas invité. Je crois que c'est la réponse à la question de votre dernier paragraphe.

1voto

Je utiliserais l'espace de noms Security et vérifierais en ligne les rôles de l'utilisateur.

using System.Threading;
using System.Security.Principal;

namespace StackOverflow_Demo
{
  class Program
  {
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        WindowsPrincipal currentPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal;

        if (currentPrincipal.IsInRole("Administrators"))
        {
            // continuer le programme
        }
        else
        {
            // générer une exception/afficher un message d'erreur - quitter le programme
        }
     }
   }
 }

Le currentUser peut démarrer votre application et recevra un message d'information s'il n'est pas membre du rôle d'administrateur!

J'espère que cela pourra vous aider!

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