UAC a besoin d'une application console
Question
J'ai une application console qui nécessite l'utilisation d'un code nécessitant un niveau administrateur. J'ai lu qu'il me fallait ajouter un fichier Manifest myprogram.exe.manifest ressemblant à ceci:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator">
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Mais cela ne soulève toujours pas le UAC (dans la console ou dans le débogage dans VS). Comment puis-je résoudre ce problème?
Mettre à jour
Je peux le faire fonctionner si j'exécute la solution dans Administrator ou si je lance le fichier /bin/*.exe dans Administrator. Je me demande toujours s'il est possible que quelque chose apparaisse au démarrage de l'application au lieu de cliquer explicitement sur > Exécuter en tant qu'administrateur?
La solution
Vous devez incorporer le manifeste UAC en tant que ressource Win32 incorporée. Voir Ajout d'un manifeste UAC au code géré .
En bref, vous utilisez un outil de ligne de commande du SDK Windows pour l'intégrer à votre exécutable.
Vous pouvez automatiser cette opération en tant qu'étape de post-génération en plaçant la ligne suivante en tant que tâche de post-génération dans les propriétés de votre projet VS:
mt.exe -manifest "$(ProjectDir)$(TargetName).exe.manifest" -updateresource:"$(TargetDir)$(TargetName).exe;#1"
Autres conseils
Pour ceux qui utilisent Visual Studio, c'est très simple. J'étais sur le point de configurer le SDK Windows et de faire les étapes post-génération mt.exe et tout cela avant de réaliser qu'il est intégré à VS. J'ai pensé l'enregistrer pour la postérité.
- projet | Ajouter un nouvel élément - > Éléments Visual C # - > Fichier de manifeste d'application
- Ouvrez le fichier app.manifest, remplacez les niveaux RequestExecutionLevel. @ par "requireAdministrator" .
- Construire
Ta-da
La réponse de Scott fera ce que vous avez demandé, mais Microsoft recommande aux applications de la console d’afficher un " accès refusé " message plutôt que demander l’élévation.
De http://msdn.microsoft.com/en-us/library /bb756922.aspx :
Une application console présente sa sortie dans la fenêtre de la console et non avec une interface utilisateur séparée. Si une application nécessite un administrateur complet jeton d'accès à exécuter, cette application doit être lancée à partir de une fenêtre de console surélevée.
Vous devez procéder comme suit pour les applications console:
Marquez que votre application est “asInvoker”: Vous pouvez le faire en créant le manifeste de votre application dans lequel vous définissez RequestedExecutionLevel == asInvoker. Cette configuration permet aux appelants de contextes non élevés de créer votre processus, ce qui leur permet de passer à l’étape 2.
Fournissez un message d'erreur si l'application est exécutée sans jeton d'accès administrateur complet: si l'application est lancée dans une console non élevée, votre application doit donner un bref message et quitter. Le message recommandé est le suivant: "Accès refusé. Des autorisations d'administrateur sont nécessaires pour utiliser les options sélectionnées. Utilisez une invite de commande de l'administrateur pour effectuer ces tâches. & Quot;
L'application doit également renvoyer le code d'erreur ERROR_ELEVATION_REQUIRED en cas d'échec du lancement pour faciliter la rédaction de scripts.
Mon code C # pour cela est ci-dessous. Il est testé sous Windows XP (administrateur - ok, utilisateur standard - > refusé) et Windows Server 2008 (administrateur élevé - > ok, administrateur non élevé - > refusé, utilisateur standard - > refusé).
static int Main(string[] args)
{
if (!HasAdministratorPrivileges())
{
Console.Error.WriteLine("Access Denied. Administrator permissions are " +
"needed to use the selected options. Use an administrator command " +
"prompt to complete these tasks.");
return 740; // ERROR_ELEVATION_REQUIRED
}
...
return 0;
}
private static bool HasAdministratorPrivileges()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}