ClickOnce Trust Model - What Should and Shouldn't You Be Able To Do Through a ClickOnce Install

Julie Lerman has a nice post about creating a desktop icon as part of a ClickOnce install – a fairly common question / request, and very representative of the kinds of “custom” things people would like to be able to do as part of a ClickOnce installation.

There were specific discussions about the option to create a desktop icon in some design reviews in Redmond I took part in several years ago. If I remember correctly, that one was dismissed mostly because it is discouraged to add desktop shortcuts as part of an install, especially without prompting the user to let them choose.

But part of this kind of desire really comes back to understanding the trust model of ClickOnce in general.

The trust issues of ClickOnce are twofold:
1.ClickOnce should not make any modifications to the local machine at install time that could affect other applications or data on the machine.
2.ClickOnce should provide runtime protections to avoid allowing the application to do harm to the local machine.

For #1, this means that you cannot install things to the GAC, add things to the registry, put things in specific places in the file system, etc. Any of those things could affect other apps and users on the machine, which means that administrators are not going to trust low-privilege users to perform ClickOnce installs. As a result, the model will not get adopted in enterprise environments, which is the primary target environment for ClickOnce – to replace those darn intranet web apps that companies create for ease of maintenance with smart client apps that give the user a better experience but are just as easy to maintain because of ClickOnce.

So the bottom line for #1 is that the only forms of customization you have available to you directly through ClickOnce is specifying:

– Whether the app is available offline (meaning you get a Start menu item and an Add or Remove Programs item)

– When updates checks will occur

– What the publisher name is – which sets what the program group in the Start menu is

– What the application name is – which sets the name of the program in the Start menu and Add or Remove Programs

– What the application icon is – through the Visual Studio application settings, and used for the icon in the Start menu item and Add or Remove Programs

There are a number of other assorted options you can set through the Publish tab, but they all really affect how the publication and deployment occurs, but none are in the form of explicit control over what goes where.

For #2 – You specify what runtime permissions the application will have as part of its publish settings (through the Security tab in VS), which end up as a list of required permissions in the application manifest. If those permissions exceed what the application would be granted by Code Access Security at runtime based on the zone of the launch URL (Internet, LocalIntranet, MyComputer, TrustedSites, or RestrictedSites), then the permissions have to be elevated either through user prompting (the default, ClickTwice experience) or through the trusted publishers capability of ClickOnce.

The fact is that you can overcome or workaround any limitations caused by #1 by exploiting #2. If you request full trust for your application, code in your application can do whatever you want it to do when your application first starts up. However, this requires one big assumption – you are also assuming the user who is running your application has sufficient privilege to do whatever it is that your code will try to do. This violates one of the goals of ClickOnce – to provide a deployment mechanism that can be used by low privilege users. So if you write some custom code in your app that tries to create a registry key – your app will have to have Registry permission through ClickOnce, and the user will have to have permission to create a key wherever your app is trying to create it.

As Julie points out, to create the Desktop icon with your own code, the user doesn’t need any special permissions because anyone can add a shortcut to their own desktop, butyou will need several high trust permissions including unmanaged code execution, which basically means most people will just elevate the application to full trust to get it done. Elevating to full trust is definitely something to avoid if you can.

The recommended way of addressing a lot of scenarios that would require high-privilege custom startup code is to create those things through the Bootstrapperas a prerequisite. A desktop icon is not really a good candidate for that, but pre-deploying something like GAC components is. Makingsomething a prerequisite may allow you to avoid requiring full trust for your application.

However, the dirty little truth about Full Trust is that even though you should always try to avoid jumping all the way to full trust, there are many things that you will likely need to do in any meaningful ClickOnce app that will require you to go to full trust. Examples include:

  • Using the ClickOnce API ApplicationDeployment class for just about anything, such as checking if this is the first run of a given version to execute your custom code, or to perform on demand updates.

  • Using WCF for remote communications

  • Using Windows Workflow in your Windows Forms application

One way to add protections back into your application even if you do have to request full trust for the application as a whole is to have sections of code where you restrict permissions below that level. You can do this through Code Access Security IStackWalk modifiers to Deny certain permissions or PermitOnly certain permissions. You can do this to bracket out a section of code (for example where you call out to some third party component to make sure that they are not doing something like reading/writing from your disk or sending information over the web for data /intelligence collection purposes). The details for doing this are too involved for this post, but I do cover it in my upcoming ClickOnce book and the underpinnings from a CAS perspective are covered well in my colleague Juval Lowy’s Programming .NET Components, Second Edition.