Getting Vista UAC elevation to work for web deployed ClickOnce applications

August 25, 2007 12:06 am

Normally you can’t have ClickOnce applications that are deployed over the web run with Vista UAC elevation prompts. It’s not something Microsoft supports. Not sure why. I guess it’s once-bitten twice-shy, coming from the whole ActiveX mess. So I guess I do kind of understand why.

There is a workaround, if you really need UAC elevation, which you shouldn’t. But at a high level, it works like this. You create your ClickOnce app like you would normally. To go with it, you create a helper app that you equip with an embedded elevation manifest. You then add a test to your ClickOnce app to see if it’s running elevated. If it isn’t you make it call the helper app. It will cause a UAC elevation prompt and in turn launch the ClickOnce app anew. Since the helper got elevated, the ClickOnce app now runs elevated too. Of course, by doing this you might end up with users not accepting the elevation request. But from what I’ve seen real users do with those elevation prompts, it won’t matter much. Anyway.

The trick is getting the helper app included in the regular ClickOnce app. There may be better ways, but here’s one I’ve spent quite some time on to work out. Maybe it will help someone out there save time, like I’ve saved time by reading posts on elevation checks using managed code. So here are the steps I’ve followed to make this work:

  1. Modify your ClickOnce app’s entry point to include elevation checks as described at http://www.itwriting.com/blog/?p=198. If the app is not running elevated, make it run the helper application and exit. The launch looks something like this:

    ProcessStartInfo

    psi = new ProcessStartInfo(“Helper.exe”);
    psi.UseShellExecute = true;
    Process.Start(psi);

    The UseShellExecute flag makes sure the UAC prompt will happen.

  2. Create your helper application with an elevation manifest (the process for that is at Catherine Heller’s blog) and have it launch your app with something like this:

    string
    appExe = Environment.GetFolderPath(Environment.SpecialFolder.Programs) + @”\YourClickOnceApp\ClickOnceApp.appref-ms”;
    Process.Start(appExe);

    As you can see the whole scenario only works if you let the ClickOnce app create a Start Menu entry.

  3. Build and publish both applications, making sure they use the option to rename the published files to .deploy extensions. This helps tremendously with web deployment.

  4. Find the published helper .deploy files and copy them to the folder that contains the ClickOnce application’s .deploy files.

  5. Open the ClickOnce application’s .exe.manifest file using MageUI. Go to the Files section and click the Populate button to include the helper app and its manifest in the fileset for the ClickOnce app. Save and sign the manifest. I used a stored certificate for the signing.

  6. Open the ClickOnce application’s .application deployment manifest using MageUI. This is probably in the directory above the .deploy files. Open the Application Reference section. Click the Select Manifest… button and browse down to the manifest you modified in step 5. Save and sign the manifest. I used the stored certificate from step 5.

  7. Now you have all the needed files packaged for uploading to your web server.

This is what will happen when the user downloads the app for the first time: A verification window shows briefly, followed by a download warning, followed by a download progress window. Now the UAC prompt will come, and if accepted, another verification window. Then the app will show.

On subsequent launches of the app the user will see the verification window, followed by the UAC prompt, followed by another verification window. Then the app will show.

It’s not pretty, but at least it works.

If you try these steps out and they don’t work, I’d appreciate an opportunity to correct them.

————————————————-

P.S.: The manifest generation step looks like this for C# projects:

“$(DevEnvDir)..\..\VC\bin\mt.exe” -manifest “$(ProjectDir)$(TargetName).exe.manifest”  ?outputresource:”$(TargetDir)$(TargetFileName)”;#1

The .exe.manifest for the helper needs to look something like this (you can leave out the commented parts):

<?

xml version=1.0 encoding=utf-8 ?>

<assembly xmlns=urn:schemas-microsoft-com:asm.v1 manifestVersion=1.0>

<assemblyIdentity version=1.0.0.0 processorArchitecture=msil name=Helper type=win32 />

<description>Helper</description>

<trustInfo xmlns=urn:schemas-microsoft-com:asm.v3>

<security>

<requestedPrivileges>

<requestedExecutionLevel level=requireAdministrator />

<!–<requestedExecutionLevel level=”asInvoker” />–>

<!– <requestedExecutionLevel level=”highestAvailable” /> –>

</requestedPrivileges>

</security>

</trustInfo>

</assembly>

7 Responses to “Getting Vista UAC elevation to work for web deployed ClickOnce applications”

ServiceController on Vista | keyongtech sent a pingback on January 18, 2009

[…] Vista elevation manifests are not supported for ClickOnce web-deployed apps. See if this helps: http://www.geektieguy.com/2007/08/25…-applications/ — Phil Wilson [MVP Windows Installer] "archimago" <archimago> wrote in message […]

Chris wrote a comment on September 18, 2009

New to C#… what is MageUI? Where is it? How do I launch it, etc, etc…. Thanks for the helpful post!

GeekTieGuy wrote a comment on September 18, 2009

MageUI is part of the .NET SDK, I believe. I’m sure if you look on msdn.microsoft.com, you’ll find plenty of information on it.

Mike S. wrote a comment on November 12, 2009

I’ve implemented part of this solution, and have run into an issue that simply a reference to Process.StartupInfo in the RunAsAdmin() function causes the ClickOnce Installer to crash.

I would think that having the ability to launch processes would be a full trust situation, which requires elevation, which is not supported in the Internet Zone.

What am I missing? What’s the manifest for the ClickOnce application supposed to look like (as opposed to the manifest for the helper application).

Help!

GeekTieGuy wrote a comment on November 12, 2009

Mike, I’m not sure. It’s been so long now. I think the manifest for the helper app needs to require admin privileges (and so does the manifest for the real app). If I remember correctly, I just added the trustInfo-security-requiredPrivileges-requestedExecutionLevel xml snippets to the manifest Visual Studio generates for a web deployment project.

Mike S. wrote a comment on November 12, 2009

I tried adding those, and got some errors – but I probably just screwed something up.
If I find out what I did wrong, I’ll update here.
THanks!

[…] (Updated 5/10/2012 – I originally claimed that it was “trivial” to make a ClickOnce app require elevation – a commenter pointed out that ClickOnce does not support the requireAdministrator execution level at all. This does not let the vendor off the hook – they should not have used ClickOnce to deploy software that requires features ClickOnce does not support… FYI – there are workarounds from the deployment side) […]

Care to comment?

%d bloggers like this: