Click here to Skip to main content
12,502,578 members (52,545 online)
Click here to Skip to main content
Add your own
alternative version

Stats

29.6K views
20 bookmarked
Posted

ClickOnce deployment vs. requestedExecutionLevel = requireAdministrator

, 1 Aug 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
How to work around a ClickOnce limitation.

Introduction

I made a small tool application that I wanted to start up every time I start up my computer. It was way too simple to make it as a Windows Service and have to install it using a windows installer. I also wanted to be able to distribute it as simple as possible to my colleagues (they're programmers, but not all that bright ;-) ). So I thought that ClickOnce deployment would be absolutely perfect for the program.

So I did it as a simple WinForms program, and I had the program add itself to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry key.

In order to do that, the program has to be run with administrator rights (elephanting irritating, but there's nothing to do about that unfortunately).

I added an application manifest to my project and changed

<requestedExecutionLevel level="asInvoker" uiAccess="false" /> 

to

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />  

and everything worked perfectly on my development machine.

Then I tried creating a ClickOnce deployment. But that proved impossible. A ClickOnce application by design cannot be run with administrator rights. So it complains already when you try to create the deployment that requireAdministrator is not a valid setting forrequestedExecutionLevel .

And then it felt like I was up the creek without a paddle. What should I do? I wanted to use ClickOnce and I wanted to run as an administrator, because the startup thing was an important part of the program. But the two things were mutually exclusive.

There had got to be a way around it, I thought, and I Googled for several hours. All I saw was: A ClickOnce application cannot be run with administrator rights.

I was about to give up when I finally found the solution. I found an article on AntsCode written by a guy called Anthony that had a working solution. You run the program, and as the first thing you do, you check if you have administrator rights. If you haven't got that, you shell yourself WITH administrator rights and close down the non-admin instance (your application cannot be a singleton application of course, but in my case it luckily wasn't that either).

It worked like a charm for me, so I thought that I'd share the tip with all y'all here.

Credits and disclaimer 

I don't claim any ownership to the code, and I don't take any credit for neither the code nor the idea. All credit should go to Anthony on AntsCode.

But in my opinion, that is the whole deal with a CodeProject tip. An article is about something you yourself have worked intensely on and want to share with the community. But a tip is about something you have found and want to tip others about because you think that they will find it interesting as well. It doesn't have to be of your own doing. That is at least how I see it. If the CodeProject admins see it differently, I hope they will enlighten me.

If you want to call plagiarism, my opinion is that it is only plagiarism if you take credit for other peoples work yourself, and as mentioned: I don't do that!

Using the code

So here's how you do it! You leave your manifest as is:

<requestedExecutionLevel level="asInvoker" uiAccess="false" /> 

And then you edit your Program.cs file like this:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
using System.Windows.Forms;

namespace MyProgramNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var wi = WindowsIdentity.GetCurrent();
            var wp = new WindowsPrincipal(wi);
 
            bool runAsAdmin = wp.IsInRole(WindowsBuiltInRole.Administrator);

            if (!runAsAdmin)
            {
                // It is not possible to launch a ClickOnce app as administrator directly,
                // so instead we launch the app as administrator in a new process.
                var processInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().CodeBase);

                // The following properties run the new process as administrator
                processInfo.UseShellExecute = true;
                processInfo.Verb = "runas";

                // Start the new process
                try
                {
                    Process.Start(processInfo);
                }
                catch (Exception)
                {
                    // The user did not allow the application to run as administrator
                    MessageBox.Show("Sorry, but I don't seem to be able to start " + 
                       "this program with administrator rights!");
                }

                // Shut down the current process
                Application.Exit();
            }
            else
            {
                // We are running as administrator
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
}  

Voila! Works like a charm (on my machine anyway)!

Points of Interest

Completely off topic, but still: I noticed a strange thing. I added the registry value to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run as mentioned, and the code went through all the way without any errors. But no matter what I did, I still couldn't see the added value in RegEdit.

It turns out that if your OS is 64 bit then there is a special hive for that. The program CLAIMS that it's adding the value to the key above, and all debugging supports that claim. But it IS in fact adding it to THIS key instead:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run

Very sneaky if you ask me!

History

  • Version 1.00 - Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Johnny J.
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden

Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!

Studied programming at the Copenhagen Engineering Academy

Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET

I now work as Senior .NET developer building Airline Booking Systems, and have a number of projects in various states of progress to work on in the spare time...

PS: The cat on my profile is one of my three cats, Ramses. He's all white, odd-eyed, deaf and definitely the coolest cat there is!

You may also be interested in...

Pro
Pro

Comments and Discussions

 
Answermy vote 5 Pin
Barış Yemişli29-Nov-14 10:55
memberBarış Yemişli29-Nov-14 10:55 
QuestionExcelente Post Pin
Member 1097664228-Jul-14 8:32
memberMember 1097664228-Jul-14 8:32 
QuestionNice one Pin
Phil Jeffrey22-Jul-14 17:45
memberPhil Jeffrey22-Jul-14 17:45 
QuestionUpdates wont work when launched this way. Pin
markitto24-Feb-14 11:44
membermarkitto24-Feb-14 11:44 
AnswerRe: Updates wont work when launched this way. Pin
Phil Jeffrey22-Jul-14 17:41
memberPhil Jeffrey22-Jul-14 17:41 
GeneralMy vote of 3 Pin
satish koladiya26-Aug-13 23:41
professionalsatish koladiya26-Aug-13 23:41 
GeneralRe: My vote of 3 Pin
Johnny J.28-Aug-13 6:54
professionalJohnny J.28-Aug-13 6:54 
QuestionThanks ... solved two issues Pin
DLipkie15-Aug-13 6:53
memberDLipkie15-Aug-13 6:53 
AnswerRe: Thanks ... solved two issues Pin
Johnny J.20-Aug-13 0:04
professionalJohnny J.20-Aug-13 0:04 
GeneralMy vote of 2 Pin
Cindy Meister10-Aug-13 6:11
memberCindy Meister10-Aug-13 6:11 
GeneralRe: My vote of 2 Pin
Johnny J.10-Aug-13 11:04
professionalJohnny J.10-Aug-13 11:04 
GeneralMy vote of 5 Pin
Santhosh Kumar Jayaraman1-Aug-13 22:46
memberSanthosh Kumar Jayaraman1-Aug-13 22:46 
GeneralMy vote of 5 Pin
VitorHugoGarcia29-Jul-13 4:35
memberVitorHugoGarcia29-Jul-13 4:35 
GeneralRe: My vote of 5 Pin
Johnny J.29-Jul-13 4:36
professionalJohnny J.29-Jul-13 4:36 
GeneralMy vote of 5 Pin
CraigDJ28-Jul-13 23:56
memberCraigDJ28-Jul-13 23:56 
GeneralRe: My vote of 5 Pin
Johnny J.29-Jul-13 0:22
professionalJohnny J.29-Jul-13 0:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160919.1 | Last Updated 2 Aug 2013
Article Copyright 2013 by Johnny J.
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid