13

I have an application which needs the UAC elevation.

I have the code which lets me give that but the application opens twice and that's an issue.

Here's the code of Form1:

public Form1()
{
    InitializeComponent();

    WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
    bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);           

    if (!hasAdministrativeRight)
    {
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.UseShellExecute = true;
        startInfo.WorkingDirectory = Environment.CurrentDirectory;
        startInfo.FileName = Application.ExecutablePath;
        startInfo.Verb = "runas";
        
        try
        {
            Process p = Process.Start(startInfo);
        }
        catch (System.ComponentModel.Win32Exception ex)
        {
            return;
        }
    }
}

Here's the code of programs.cs:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

By debugging I found out that first it executes

Process p = Process.Start(startInfo);

which opens the application UAC elevation dialog and then opens the application

but then it goes to the

Application.Run(new Form1());

in main() and opens the application again.

I don't want it to open the app again.

I am new to this so I am asking is there anything I am doing wrong and do I need to close the UAC once its open?

Andreas
  • 5,393
  • 9
  • 44
  • 53
user175084
  • 4,550
  • 28
  • 114
  • 169
  • So this worked fine for me.. since i was runnig from VS it asked me to restart the application, which i did. then it asked me to that it will make changes in my computer.. but i saw in info that those changes were only going to affect the current app. so i allowed it. now this application has elevated UAC permission. i ran anothe application and saw that i am not an administrator, which is desired. – user175084 Jun 20 '11 at 15:31

4 Answers4

32

You don't need to meddle with all that to make sure that your application always runs with elevated privileges. You can simply add an application manifest which instructs Windows to run your app elevated, and the UAC prompt will appear without you needing to write a single line of code.

There's a related question with an answer that also describes how to add a manifest here: How can I embed an application manifest into an application using VS2008?

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • i tried using this but now when i run the app from VS, it asks me to "restart under different credentials" and if i do that it wants to make changes to the computer..?? is this safe? i mean i dont want to do this permanently just for this application.. – user175084 Jun 20 '11 at 15:09
  • 5
    The application is requiring administrative privileges, just as you asked it to do. – J. Steen Jun 20 '11 at 15:09
  • 4
    Because you're not running Visual Studio as an elevated process, most likely. Since you're starting the application from Visual Studio, Visual Studio needs to be elevated to be capable of starting an elevated process. – J. Steen Jun 20 '11 at 15:12
  • 1
    We're here to help, no worries. =) – J. Steen Jun 20 '11 at 15:13
  • Here's a [great answer](http://stackoverflow.com/a/7666459/744014) with very specific instructions on how to setup the app manifest for elevated privileges. – Scott Feb 02 '17 at 16:40
5

Move the WindowsPrincipal code from your Form to Program.cs as in the example below. This will prompt the user for UAC authority prior to launching any forms and will only launch the form if UAC authority has been granted.

        static void Main()
        {
            WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);

            if (!hasAdministrativeRight)
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.WorkingDirectory = Environment.CurrentDirectory;
                startInfo.FileName = Application.ExecutablePath;
                startInfo.Verb = "runas";
                try
                {
                    Process p = Process.Start(startInfo);
                    Application.Exit();
                }
                catch (System.ComponentModel.Win32Exception ex)
                {
                    MessageBox.Show("This utility requires elevated priviledges to complete correctly.", "Error: UAC Authorisation Required", MessageBoxButtons.OK);
//                    Debug.Print(ex.Message);
                    return;
                }
            }
            else
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
Martyn Talbot
  • 51
  • 1
  • 1
3

Elevating your privileges is always going to start a new process. There is no way around that, other than starting with elevated privileges in the first place by setting your application to require administrative privileges. What you can do is end the application right after the elevated process starts, so that you only have one application running.

This scenario is usable for applications that only require certain parts of their function to be elevated - such as an automatically self-updating installer that needs access to Program Files - and not one that requires administrative access all the time.

J. Steen
  • 15,470
  • 15
  • 56
  • 63
  • so i did add this this.Close(); Application.Exit(); after Process p = Process.Start(startInfo); but then it gives an error message at Application.Run(new Form1()); "Cannot start a disposed application"?? – user175084 Jun 20 '11 at 14:55
  • 1
    I would urge you to check the other answers as well, for alternative ways to achieve what you want. – J. Steen Jun 20 '11 at 14:56
3

This is a much better approach when your application is known to require Admin privileges from the start.

Shashank Shekhar
  • 3,958
  • 2
  • 40
  • 52
Bueller
  • 2,336
  • 17
  • 11
  • i tried using this but now when i run the app from VS, it asks me to "restart under different credentials" and if i do that it wants to make changes to the computer..?? is this safe? i mean i dont want to do this permanently just for this application.. – user175084 Jun 20 '11 at 15:09
  • 2
    Safe is relative. You are obviously doing something inherantly unsafe because you need elevated permissions in your application. Adding the manifest to your application only effects the application you are working on so will not effect your other projects unless you include the manifest in those applications as well. Running VS with elevated privileges all the time is not how I do it and I can't really address what vulnerabilities this might open for you because some of that will be dependant on addins and other factors. – Bueller Jun 20 '11 at 15:15
  • You can view an archived version of [the article](https://web.archive.org/web/20160618011039/http://www.aneef.net/2009/06/29/request-uac-elevation-for-net-application-managed-code/) using the Internet Archive Wayback Machine. – Scott Feb 02 '17 at 16:35