Pregunta

Tengo esta aplicación que necesita hacer algunas cosas en rutas protegidas (como% PROGRAMFILES%), sé que debería usar% APPDATA%, pero no puedo cambiar eso por ahora. He aislado todas las cosas que podrían requerir que UAC aparezca en otro proyecto, aquí hay un código de muestra:

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

Entonces, llamo a este ejecutable desde mi programa principal, y si falla debido a un acceso no autorizado, se iniciará mostrando la solicitud de UAC.

Mis preguntas son:

1) Tuve que convertir la salida del proyecto de una DLL a un EXE porque no pude encontrar ninguna forma de solicitar la elevación de UAC desde una DLL, ¿hay alguna manera fácil de hacerlo?

2) También noté que algunos programas muestran un mensaje UAC personalizado, con el logotipo del programa y todas esas cosas, déjenme mostrarles un ejemplo:

Ugly UAC

UAC personalizado

¿Cómo puedo hacer eso para mi programa?

3) Para evitar entrar en un bucle cuando se ejecuta con privilegios elevados y obtiene otra excepción de acceso no autorizado, hice esa cosa pasando cualquier argumento. ¿Qué harías para lograr el mismo objetivo?

Creo que eso es todo por ahora. Gracias por tu tiempo.

¿Fue útil?

Solución

1 no puede controlar el modo de elevación del proceso que aloja su DLL. Puede conceder permiso a la carpeta o registro de destino para todos durante el proceso de instalación si puede controlar el proceso de instalación.

2 necesita firmar el programa con un certificado publicado por una autoridad de certificación en la que el cliente confiaría . Visite su tienda de certificados local (panel de control- > opciones de internet, pestaña de contenido, editores) para ver autoridades de certificación comunes.

3 cuando obtenga UnauthorizedAccessExceotion, tírelo al host exe o devuelva un valor de error que indica un problema de seguridad. La persona que llama de su DLL luego decide qué hacer, como mostrar un cuadro de diálogo de error de seguridad para informar al usuario si el programa ya está elevado (¿permiso no otorgado por el controlador de dominio?), O reiniciar el proceso en modo elevado utilizando el comando runas si no está elevado.

Otros consejos

Tuve los mismos problemas. Buscando en Google alrededor de 2 días, encontré la única solución que se ajustaba a mis necesidades: iniciar la aplicación con derechos administrativos. Inicio la aplicación, verifico si se ejecuta como administrador. Y si no es así, reinícielo con derechos 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top