Domanda

Ho questa applicazione che deve fare alcune cose in percorsi protetti (come% PROGRAMFILES%), so che dovrei usare% APPDATA%, ma per ora non posso cambiarlo. Ho isolato tutte le cose che potrebbero richiedere il controllo dell'account utente per la visualizzazione su un altro progetto, ecco un codice di esempio:

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);
        }
    }
}

Quindi, chiamo questo eseguibile dal mio programma principale, e se fallisce a causa di un accesso non autorizzato, si avvierà mostrando la richiesta UAC.

Le mie domande sono:

1) Ho dovuto convertire l'output del progetto da una DLL in un EXE perché non riuscivo a trovare un modo per richiedere l'elevazione UAC da una DLL, c'è un modo semplice per farlo?

2) Ho anche notato che alcuni programmi mostrano un messaggio UAC personalizzato, con il logo del programma e tutte quelle cose, lascia che ti mostri un esempio:

Ugly UAC

UAC personalizzato

Come posso farlo per il mio programma?

3) Per evitare di entrare in un ciclo quando è in esecuzione con privilegi elevati e si ottiene un'altra UnauthorizedAccessException ho fatto quella cosa passando qualsiasi argomento. Cosa faresti per raggiungere lo stesso obiettivo?

Penso che sia tutto per ora. Grazie per il tuo tempo.

È stato utile?

Soluzione

1 non puoi controllare la modalità elevazione del processo che ospita la tua DLL. Puoi concedere l'autorizzazione alla cartella o al registro di destinazione per tutti durante il processo di installazione se puoi controllare il processo di installazione.

2 devi firma il programma con un certificato pubblicato da un'autorità di certificazione ritenuta attendibile dal cliente . Visita il tuo archivio certificati locale (pannello di controllo - Opzioni Internet, scheda Contenuto, editori) per vedere le autorità di certificazione comuni.

3 quando ricevi UnauthorizedAccessExceotion, lancialo sull'exe di hosting o restituisci un valore di errore che indica un problema di sicurezza. Il chiamante della DLL decide quindi cosa fare, ad esempio la visualizzazione di una finestra di dialogo di errore di sicurezza per informare l'utente se il programma è già elevato (autorizzazione non concessa dal controller di dominio?) O riavvio del processo in modalità elevata utilizzando il comando runas se non è elevato.

Altri suggerimenti

Ho avuto gli stessi problemi. Cercando su Google circa 2 giorni ho trovato l'unica soluzione adatta alle mie esigenze: avviare l'applicazione con diritti amministrativi. Avvio l'applicazione, controllo se viene eseguita come amministratore. E in caso contrario, riavvia con diritti amministrativi.

    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;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top