Question

J'ai cette application qui doit faire certaines choses dans des chemins protégés (comme% PROGRAMFILES%), je sais que je devrais utiliser% APPDATA%, mais je ne peux pas changer cela pour l'instant. J'ai isolé toutes les choses qui pourraient nécessiter que UAC apparaisse sur un autre projet, voici un exemple de code:

using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

class Class1
{
    static void Main(string[] args)
    {
        try
        {
            File.CreateText(Path.Combine(Application.StartupPath, "something.txt"));
        }
        catch (UnauthorizedAccessException ex)
        {
            MessageBox.Show(ex.Message, "UnauthorizedAccessException", MessageBoxButtons.OK, MessageBoxIcon.Error);

            if (args.Length == 0)
            {
                Process proc = new Process();
                proc.StartInfo.FileName = Application.ExecutablePath;
                proc.StartInfo.Arguments = "not again";
                proc.StartInfo.Verb = "runas";
                proc.Start();
            }
            else
            {
                MessageBox.Show("Exit to avoid loop.");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

J'appelle donc cet exécutable depuis mon programme principal. S'il échoue à cause d'un accès non autorisé, il se lancera lui-même en affichant la requête UAC.

Mes questions sont les suivantes:

1) Je devais convertir la sortie du projet d'une DLL en un fichier EXE car je ne trouvais aucun moyen de demander une élévation UAC à partir d'une DLL. Existe-t-il un moyen simple de le faire?

2) J'ai également remarqué que certains programmes affichent un message UAC personnalisé, avec le logo du programme et toutes ces choses, laissez-moi vous montrer un exemple:

UAC laid

UAC personnalisé

Comment puis-je faire cela pour mon programme?

3) Pour éviter d'entrer dans une boucle lorsqu'il s'exécute avec des privilèges élevés, il obtient une autre exception UnauthorizedAccessException. Je l'ai fait en passant des arguments. Que feriez-vous pour atteindre le même objectif?

Je pense que c'est tout pour le moment. Merci pour votre temps.

Était-ce utile?

La solution

1, vous ne pouvez pas contrôler le mode d'élévation du processus hébergeant votre DLL. Vous pouvez accorder un droit d'accès au dossier ou au registre cible pour tout le monde lors du processus d'installation si vous pouvez contrôler le processus d'installation.

2, vous devez signer le programme avec un certificat publié par une autorité de certification qui serait approuvée par le client . Rendez-vous dans votre magasin de certificats local (panneau de configuration - options Internet, onglet Contenu, éditeurs) pour connaître les autorités de certification communes.

3 lorsque vous obtenez UnauthorizedAccessExceotion, envoyez-le à l'exécutable d'hébergement ou renvoyez une valeur d'erreur indiquant un problème de sécurité. L’appelant de votre DLL décide ensuite quoi faire, tel qu’afficher une boîte de dialogue d’erreur de sécurité pour informer l’utilisateur si le programme est déjà élevé (autorisation non octroyée par le contrôleur de domaine?) Ou redémarrer le processus en mode élevé à l'aide de la commande runas s'il n'est pas élevé.

Autres conseils

J'ai eu les mêmes problèmes. Googler pendant environ 2 jours, j’ai trouvé la seule solution qui répond à mes besoins: démarrez l’application avec des droits d’administrateur. Je lance l'application, vérifie si elle est exécutée en tant qu'administrateur. Et si ce n'est pas le cas, redémarrez avec les droits d'administration.

    static void Main(string[] args)
    {
        if (NeedElevation(args) && Elevate(args))
        { // If elevastion succeeded then quit.
            return;
        }
        // your code here
    }

    public static bool Elevate(string[] args)
    {
        try
        {
            ProcessStartInfo info = Process.GetCurrentProcess().StartInfo;
            info.Verb = "runas";
            info.Arguments = NoElevateArgument;
            foreach (string arg in args)
            {
                info.Arguments += ' ' + arg;
            }
            info.FileName = Assembly.GetEntryAssembly().Location;

            Process process = new System.Diagnostics.Process();
            process.StartInfo = info;

            process.Start();
        }
        catch (Exception)
        {
            MessageBox.Show("You don't have administrative privileges thus the Automatic Application Updates cannot be started. But the rest of application is available as usually.",
                "Not enough user rights", MessageBoxButtons.OK, MessageBoxIcon.Information);
            return false;
        }

        return true;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top