Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pimp my UAC and a few questions about it

I have this application that need to do some things in protected paths (like %PROGRAMFILES%), I know that I should be using %APPDATA%, but I can't change that for now. I have isolated all the things that could require UAC to show up on another project, here's a sample 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);
        }
    }
}

So, I call this executable from my main program, and if it fails because of an unauthorized access, it will launch itself showing the UAC request.

My questions are:

1) I had to convert the project output from a DLL to an EXE because I couldn't find any way to request UAC elevation from a DLL, is there any easy way to do that?

2) I also noticed that some programs show a personalized UAC message, with the program logo and all those things, let me show you an example:

Ugly UAC

Personalized UAC

How can I do that for my program?

3) To avoid entering in a loop when is running with elevated privileges an it gets another UnauthorizedAccessException I did that thing passing any args. What would you do to achieve the same goal?

I think that's all for now. Thanks for your time.

like image 487
Tute Avatar asked Oct 27 '09 15:10

Tute


2 Answers

I had same problems. Googling around about 2 days I found the only solution that fit my needs - start the application with administrative rights. I start the application, check if it being run as admin. And if doesn't - restart it with administrative rights.

    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;
    }
like image 135
Vasyl Boroviak Avatar answered Sep 30 '22 16:09

Vasyl Boroviak


1 you can not control the elevation mode of the process hosting your DLL. You can grant permission to the target folder or registry for everyone during the install process if you can control install process.

2 you need to sign the program with a certificate published by a certificate authority that would be trusted by the client. Visit your local certificate store (control panel->internet options, content tab, publishers) to see common certificate authorities.

3 when you get UnauthorizedAccessExceotion, throw it to the hosting exe or return an error value indicating a security problem. The caller of your DLL then decide what to do, such as displaying a security error dialog to inform the user if the program is already elevated (permission not granted by domain controller?) , or restarting the process in elevated mode using the runas command if it is not elevated.

like image 34
Sheng Jiang 蒋晟 Avatar answered Sep 30 '22 16:09

Sheng Jiang 蒋晟