Pergunta

Eu tenho esse aplicativo que necessidade de fazer algumas coisas em caminhos protegidos (como% PROGRAMFILES%), Eu sei que eu deveria estar usando% APPDATA%, mas não posso mudar isso para agora. Isolei todas as coisas que possam exigir a UAC a aparecer em outro projeto, aqui está um código de exemplo:

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

Então, eu chamo este executável do meu programa principal, e se ele falhar devido a um acesso não autorizado, que vai lançar em si mostrando o pedido UAC.

As minhas perguntas são:

1) eu tinha que converter a saída do projeto a partir de uma DLL a um EXE, porque eu não poderia encontrar alguma maneira de elevação pedido UAC de uma DLL, há alguma maneira fácil de fazer isso?

2) Notei também que alguns programas de mostrar uma mensagem UAC personalizado, com o logotipo do programa e todas aquelas coisas, deixe-me mostrar-lhe um exemplo:

UAC Feio

UAC personalizado

Como posso fazer isso para o meu programa?

3) Para evitar entrar em um loop quando está sendo executado com privilégios elevados um fica outra UnauthorizedAccessException eu fiz essa coisa de passar quaisquer argumentos. O que você faria para alcançar o mesmo objetivo?

Eu acho que é tudo por agora. Obrigado pelo seu tempo.

Foi útil?

Solução

1 você não pode controlar o modo de elevação do processo de hospedagem sua DLL. Você pode conceder permissão para a pasta de destino ou de registro para todos durante o processo de instalação se você pode controlar processo de instalação.

2 Você precisa assinar o programa com um certificado publicado por uma autoridade de certificação que seria confiado pelo cliente. Visite o seu armazenamento de certificados local (painel de controle-> Opções da Internet, guia de conteúdo, editores) para ver as autoridades de certificação comum.

3 quando você começa UnauthorizedAccessExceotion, jogá-lo para o exe hospedagem ou devolver um valor de erro indicando um problema de segurança. O chamador de sua DLL, em seguida, decidir o que fazer, como exibir uma caixa de diálogo de erro de segurança para informar ao usuário se o programa já é elevado (permissão não concedida pelo controlador de domínio?), Ou reiniciando o processo no modo elevado usando o comando runas se não é elevado.

Outras dicas

Eu tive mesmos problemas. Pesquisando em torno de aproximadamente 2 dias eu encontrei a única solução que se encaixam minhas necessidades - iniciar a aplicação com direitos administrativos. Eu iniciar a aplicação, verificar se ele está sendo executado como administrador. E se não -. restart com direitos administrativos

    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;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top