Walkthrough: Integrating ClickOnce for a Managed Object Model

This walkthrough shows how to incorporate ClickOnce deployment into the ShapeAppBasicCSharp sample application. Add-in developers can use ClickOnce to deploy and help secure the add-ins that they create for your host application.

You can perform this walkthrough as a stand-alone walkthrough, or you can perform it as part of the series of walkthroughs that is described in Walkthrough: Integrating Visual Studio Tools for Applications with ShapeApp.

This walkthrough illustrates the following tasks:

  • Discovering and loading add-ins that were deployed by using ClickOnce.

  • Creating and signing application and deployment manifests.

Prerequisites

You must have the following components to complete this walkthrough:

  • Visual Studio 2008.

  • Windows SDK.

  • Microsoft Visual Studio Tools for Applications 2.0.

  • The ShapeAppBasicCSharp sample and ShapeAppCSharpAddIns add-in extracted to the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp folder on the development computer and registered. For more information about how to extract and register ShapeAppBasicCSharp, see How to: Build and Run the ShapeAppBasicCSharp Sample.

Opening the Solution

Open the ShapeAppBasicCSharp solution in Visual Studio.

To open the ShapeAppBasicCSharp solution

  1. Start Visual Studio.

  2. On the File menu, point to Open, and then click Project/Solution.

  3. In the Open Project dialog box, locate the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp folder.

  4. Select ShapeAppBasicCSharp.sln, and then click Open.

Discovering and Loading Add-Ins

Discover and load add-ins by using ClickOnce with the AddInStoreExtensions and AddInTokenExtensions classes. The VerifyAddInTrust method is used to analyze the certificate that is used to sign the manifests. The VerifyAddInPermissions method is used to read permissions from the manifests. In your implementation of the IClickOnceAddInTrustManager interface, verify the trust evidence for the add-ins. For more information, see Securing Add-ins by Using ClickOnce.

To evaluate add-in security

  1. In Solution Explorer, right-click the ShapeAppBasicCSharp project, point to Add, and then click Class.

  2. Change the name of the class to SecurityEvaluator.cs, and then click Add.

  3. Right-click SecurityEvaluator.cs, and then click View Code.

  4. Replace the using statements with the following list.

    using System;
    using Microsoft.VisualStudio.Tools.Applications.Deployment;
    
  5. Replace the definition of the SecurityEvaluator class with the following code to implement the IClickOnceAddInTrustManager interface.

    internal class SecurityEvaluator : IClickOnceAddInTrustManager
    {
        internal SecurityEvaluator() { }
    
        public void VerifyAddInPermissions(System.Security.PermissionSet permissions)
        {
            // Verify that the add-in has the permission set
            // that is required by your security policy.
        }
    
        public void VerifyAddInTrust(ClickOnceAddInTrustEvidence evidence)
        {
            // Verify that the add-in has the evidence that is
            // required by your security policy.
        }
    }
    

Loading Add-ins

To load add-ins by using ClickOnce, create a ClickOnceAddInDeploymentManager object.

To load add-ins by using ClickOnce

  1. In Solution Explorer, expand the ShapeAppBasicCSharp project.

  2. Right-click VstaRunTimeIntegration.cs, and then click View Code.

  3. Add the following using statement.

    using Microsoft.VisualStudio.Tools.Applications.Deployment;
    using System.Threading;
    
  4. Add the following fields to the VstaRunTimeIntegration class.

    internal const string ClickOncePrefix = "/clickonce:";
    
  5. Replace the Connect method with the following code. This calls the LoadClickOnceAddIn method for loading ClickOnce add-ins.

    internal void Connect(Application hostApplication)
    {
        this.application = hostApplication;
    
        // Create a service provider
        this.InstantiateServiceProvider();
    
        // Load add-ins with ClickOnce.
        LoadClickOnceAddIn();
    }
    
  6. Add the following LoadClickOnceAddIn method, which shows how to download and install a ClickOnce-enabled add-in. The downloading process is on another thread so that the graphical user interface (GUI) stays responsive to the user. The add-in is copied to the ClickOnce cache when installation is finished. You can increase the time-out, depending on the network speed.

    private void LoadClickOnceAddIn()
    {
        string[] args = Environment.GetCommandLineArgs();
    
        foreach (string arg in args)
        {
            if (arg.StartsWith(ClickOncePrefix))
            {
                string url = arg.Remove(0, ClickOncePrefix.Length);
                SecurityEvaluator trustManager = new SecurityEvaluator();
                ClickOnceAddInDeploymentManager clickOnceManager = 
                    new ClickOnceAddInDeploymentManager(new Uri(url), trustManager);
    
                // Wait for the download and install.
                clickOnceManager.Timeout = new TimeSpan(0, 5, 0);
                AddInInformation retInfo = null;
    
    
                Exception exOriginalThread = null;
                Thread installerThread =
                new Thread(
                new ThreadStart(
                delegate
                {
                    try
                    {
                        // Install and load the add-in.
                        retInfo = clickOnceManager.InstallAddIn();
                    }
                catch (Exception ex)
                {
                    exOriginalThread = ex; 
                }
                }));
    
                installerThread.Name = "InstallerThread";
                installerThread.Start();
                installerThread.Join();
                if (exOriginalThread != null)
                {
                    throw exOriginalThread;
                }
                ActivateAddIn(clickOnceManager, retInfo);
            }
        }
    }
    
  7. Add the following method to the VstaRunTimeIntegration class. The ActivateAddIn method loads the add-in that has been installed by using ClickOnce.

    private void ActivateAddIn(ClickOnceAddInDeploymentManager mgr, AddInInformation info)
    {
        System.Collections.ObjectModel.Collection<AddInToken> addins = 
            AddInStoreExtensions.FindAddIn(info, 
            AddInStoreExtensions.DefaultPipelinePath, 
            typeof(IExtendedEntryPoint));
        IExtendedEntryPoint addin = 
            addins[0].Activate<IExtendedEntryPoint>(AddInSecurityLevel.FullTrust);
        addin.Initialize(this.serviceProvider);
        addin.InitializeDataBindings();
        addin.FinishInitialization();
        addInList.Add(addin);
    }
    
  8. In Solution Explorer, right-click Application.cs, and then click View Code.

  9. Replace the Application method with the following code. Doing this lets you avoid parsing the ClickOnce arguments as a file path. You can use any approach to start the ClickOnce add-in installation, such as a unique file name extension and MIME type.

    internal Application(string[] args)
    {
        string cmdArgDocPath = null;
        for (int i = 0; i < args.Length;i++ )
        {
            // Ignore the ClickOnce arguments.
            if (!args[i].StartsWith(VstaRunTimeIntegration.ClickOncePrefix) && (i > 0))
            {
                cmdArgDocPath = args[i];
            }
        }
        // Initialize the application form.
        form = new ShapeAppForm(this);
    
        // Initialize the available shapes.
        shapes = new ShapeCollection();
        int Y = 10;
        initShape(new Circle(), new Color(System.Drawing.Color.Red), ref Y);
        initShape(new Square(), new Color(System.Drawing.Color.Blue), ref Y);
        initShape(new Triangle(), new Color(System.Drawing.Color.Green), ref Y);
        initShape(new Octagon(), new Color(System.Drawing.Color.Purple), ref Y);
        initShape(new Star(), new Color(System.Drawing.Color.Orange), ref Y);
    
        form.toolboxPanel.Width = 70 + form.toolboxPanel.Padding.Left + form.toolboxPanel.Padding.Right;
        form.toolboxPanel.Invalidate();
    
        document = new Document(this);
        if (!String.IsNullOrEmpty(cmdArgDocPath))
            document.Open(cmdArgDocPath);
        else
            NewDocument();
    }
    

Checkpoint

Build and debug your project to ensure that it compiles and runs without errors.

To build and debug your project

  • Press F5.

    Verify that the project builds without errors, and that ShapeApp opens.

Creating and Signing ClickOnce Manifests

Now you create and sign manifests that describe the ShapeApp add-in. Although it is the responsibility of add-in developers to generate the application and deployment manifests for their add-ins, the host application can create build tasks that generate manifests on behalf of the add-in developers. Afterwards, the add-in developers can sign the manifests by using their own certificates. For more information, see Deploying Add-ins by Using ClickOnce.

Creating a Certificate

You must sign your application and deployment manifests by using a certificate. You can use Visual Studio to create a test certificate. For final deployment, obtain a certificate from a certification authority.

To create a certificate

  1. On the Project menu, click ShapeAppBasicCSharp Properties.

  2. On the Signing tab, select Sign the ClickOnce manifests.

  3. Click Create Test Certificate.

  4. In the Create Test Certificate dialog box, in the two text boxes, type a password for the new certificate.

  5. Clear Sign the ClickOnce manifests.

  6. In the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp\Core folder, copy ShapeAppBasicCSharp_TemporaryKey.pfx, and then paste it in %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp\Sample AddIns\CSharp\AppLevel\Bin\Debug folder.

Creating and Signing Manifests

To create application and deployment manifests by using the Manifest Generation and Signing Tool (Mage.exe), you must have the Windows SDK installed.

To create the ClickOnce application and deployment manifests for the add-in

  1. Open a Visual Studio Command Window.

  2. At the command prompt, change the directory to %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp\Sample AddIns\CSharp\Applevel\Bin\Debug.

  3. Run the following command to create an application manifest.

    mage -New Application -ToFile ShapeAppCSharpAppAddIn.dll.manifest -Name "Shape App CSharp Add-in with ClickOnce manifests" -Version "1.0.0.0" -FromDirectory .
    

    The ShapeAppCSharpAppAddIn.dll.manifest is created.

  4. Open ShapeAppCSharpAppAddIn.dll.manifest in the Visual Studio XML editor.

  5. Add the following text to the end of the file but before the last </asmv1:assembly> element:

    <vstav2:addIn xmlns:vstav2="urn:schemas-microsoft-com:vsta.v2">
      <vstav2:entryPoints>
        <vstav2:entryPoint class="ShapeAppCSharpAppAddIn.AppAddIn">
                <assemblyIdentity 
                  name="ShapeAppCSharpAppAddIn" 
                  version="1.0.2897.25791" 
                  language="neutral" 
                  processorArchitecture="msil" />
                </vstav2:entryPoint>
      </vstav2:entryPoints>
      <vstav2:update enabled="true">
        <vstav2:expiration maximumAge="7" unit="days" />
      </vstav2:update>
    </vstav2:addIn>
    
  6. Save and close ShapeAppCSharpAppAddIn.manifest.

  7. At the command prompt, run the following command to sign the application manifest. Enter your password for the certificate at the end of this command.

    mage -sign ShapeAppCSharpAppAddIn.dll.manifest -CertFile ShapeAppBasicCSharp_TemporaryKey.pfx -Password Password
    
  8. Run the following command to create a deployment manifest.

    mage -New Deployment -ToFile ShapeAppCSharpAppAddIn.vsta -Name "Shape App CSharp Add-in with ClickOnce manifests" -Version "1.0.0.0" -AppManifest ShapeAppCSharpAppAddIn.dll.manifest
    
  9. Run the following command to sign the deployment manifest. Enter your password for the certificate at the end of this command.

    mage -sign ShapeAppCSharpAppAddIn.vsta -CertFile ShapeAppBasicCSharp_TemporaryKey.pfx -Password Password
    

Installing and Loading the Add-in

To install and load the add-in, pass in the deployment manifest to ShapeApp.

To install and load the ClickOnce add-in

  1. In Visual Studio, on the Project menu, click ShapeAppBasicCSharp Properties.

  2. On the Debug tab, in the command-line arguments, type the following command.

    /clickonce:"%SYSTEMDRIVE%\ShapeAppSamples\ShapeAppBasicCSharp\sample addIns\CSharp\Applevel\bin\debug\ShapeAppCSharpAppAddIn.vsta"
    
  3. Press F5.

    The ShapeApp application starts.

  4. Verify that ShapeApp displays a series of messages. These messages are displayed by the add-in that you created by building the ShapeAppCSharpAddIns solution.

  5. Exit ShapeApp.

See Also

Tasks

How to: Configure the ClickOnce Trust Prompt

Concepts

Securing and Deploying Add-Ins

Securing Add-ins by Using ClickOnce

How to: Sign Application and Deployment Manifests with Mage.exe

Deploying Add-ins by Using ClickOnce

Walkthrough: Integrating ClickOnce for a Managed Object Model

Other Resources

Visual Studio Tools for Applications 2.0