How To: Use Global Customizations for ClickOnce and VSTO/Office Applications (KB14)

This article provides guidance on how to correctly customize the SLPS Runtime components for use with Office (VSTO) extensions and ClickOnce applications. The default per-machine licensing approach uses a license repository located in the registry under HKEY_LOCAL_MACHINE.  However, due to installation restrictions imposed by the lack of an administrator-privilege installation step in ClickOnce and VSTO applications there is no central place on a computer where one could persist licenses and still allow all the users to access a shared single license.

In versions 3.0.1908-3.0.1914 of the SLP Runtime, the customization approach was as described in http://support.inishtech.com/KB11.

As of 3.1.1915, the following approach applies. Porting between the two approaches requires minimal work. If you need any assistance or further information regarding porting, please contact Support.

Per-user and Per-machine Licensing

NOTE: For background information on SLPS Runtime installation which may be useful in understanding what's involved in making the SLPS ClickOnce and VSTO support work, please read http://support.inishtech.com/KB7

The default license store for SLPS needs write access to its key in the Registry under HKEY_LOCAL_MACHINE. 

For normal applications, one adds a step to one’s MSI installer which, while running with elevated privileges at installation time, configures the registry in such a way as to allow the requisite actions to be performed when the application runs even when running as a normal user without elevated privileges. 

In the case of ClickOnce and VSTO applications, there is no 'install step', and even FullTrust does not give one a way to elevate in any normal-user accessible manner.  Another key underpinning of ClickOnce is that apps should not know about each other or be able to share data in any way.  For this reason, the install directory name internally is a random GUID deep inside the user's profile, which is effectively treated as a cache by the loader - the canonical source of the application is really the .application manifest file on the source download site.

As a result of these restrictions, there is not a central place on a computer where one could store things such as licenses (even in a file) yet still allow all the users to shared a single license (or any other).

Applying a HKCU Registry redirection policy

  1. Add a Global Customization management class

  2.     public class SlpServicesIntegration
        {
            public const string PermutationShortCode =; // TODO: please insert your permutation short code, e.g.: "c637e"
    
            static SlpServicesIntegration()
            {
                GlobalCustomizations.Instance.PermutationCustomizationsFor( PermutationShortCode ).Customize += CustomizePermutation;
            }
    
            public static void Initialize()
            {
                // the real work is done just once in the static initializer, but something will need to trigger its execution
            }
    
            static void CustomizePermutation( object sender, PermutationCustomizations.CustomizeEventArgs args )
            {
                args.Customizations.StoreLocation = StoreLocation.UserProfile;
            }
        } 
  3. Triggering the Integration:

  • ClickOnce EXE Applications (e.g. WPF, WinForms etc.)
    class Program
    {
        [STAThread] // If licensing dialog pops up [or any other WinForms file dialog], it needs to be on an STA thread or the application will hang when the user goes to select the .bin file
        static void Main()
        {
            SlpServicesIntegration.Initialize();

           <<the rest of your mainline code>>
  • VSTO/Office addins
        void ThisAddIn_Startup( object sender, System.EventArgs e )
        {
            SlpServicesIntegration.Initialize();

            <<any other initialization you need>>

Troubleshooting

Storage Not Configured Exceptions

If you get a store not initialized exception, it means the Triggering step (#2 above) has not been completed successfully prior to the first execution of protected code in one’s application

Running Visual Studio as Administrator and/or running with UAC off

When running Visual Studio as administrator (e.g., in order to be able to Publish Click Once apps, run against IIS etc.), the instance of the browser (e.g., Internet Explorer) that gets invoked to show the ClickOnce publish page is ALSO RUNNING WITH ELEVATED PRIVILEGES, i.e., AS ADMINISTRATOR IF VISUAL STUDIO IS. This means that clicking on the install button will behave differently (even on Vista and later versions of Windows) than starting a new [non-elevated] browser window and going to the same URL. In other words, if you want to test what your users will experience, you need to copy the URL from the browser Visual Studio shows after the publish into a manually loaded browser (i.e., to ensure that the Click Once app and/or VSTO app will NOT be elevated during the ClickOnce invocation)

Legacy Porting issues

If you receive the following exception:

System.InvalidOperationException: SLPS: FATAL ERROR: Limiting machine licenses to user due to appSetting: Slps.RedirectMachineToUser is no longer supported. Please refer to http://support.inishtech.com/KB11 for details regarding suitable migration and workaround approaches.

this indicates that you should:

  1. Remove the Slps.RedirectMachineToUser  appSetting from one’s app.config
  2. Employ the simplified approach detailed in this article to have the runtime apply the same policy as implemented via the previous guidance