Walkthrough: Modifying an Application to Load Add-Ins

This walkthrough provides step-by-step instructions for modifying the ShapeAppCSharp sample application so that it uses Visual Studio Tools for Applications to discover and load add-ins. ShapeAppCSharp is a sample that demonstrates the process of integrating Visual Studio Tools for Applications with an application that is written using Visual C#. For more information about ShapeAppCSharp, see ShapeApp Samples (Visual Studio Tools for Applications)

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

This walkthrough illustrates the following tasks:

  • Creating a host item provider and a type map provider. These services enable add-ins to call into the host application and access the types in the object model of the host application. For more information, see Implementing Host Services.

  • Discovering and loading add-ins by using the AddInStore and AddInToken classes in the .NET Framework. For more information, see Discovering and Loading Add-Ins.

Prerequisites

You need the following components to complete this walkthrough:

  • Visual Studio 2008.

  • Visual Studio Tools for Applications.

  • Two samples extracted and built on your computer:

    • The ShapeAppCSharp sample extracted to the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppCSharp folder. You will integrate Visual Studio Tools for Applications with this sample.

    • The ShapeAppCSharpBasic sample extracted to the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppCSharpBasic folder. At the end of this walkthrough, you will use the add-in project that is included in this sample to test your integration.

    For more information about extracting, building, and registering these samples, see the following topics:

Opening the Solution

Open the solution for the ShapeAppCSharp sample in Visual Studio.

To open the ShapeAppCSharp solution

  1. Start Visual Studio.

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

  3. In the Open Project dialog, navigate to the %SYSTEMDRIVE%\ShapeAppSamples\ShapeAppCSharp folder.

  4. Select the ShapeAppCSharp.sln file, and click Open.

Adding References to the Project

The first step is to add references to Visual Studio Tools for Applications assemblies to the ShapeAppCSharp project. These references must be in the project before you can modify ShapeAppCSharp to load add-ins.

To add the required references

  1. In Solution Explorer, right-click References under the ShapeAppCSharp project, and then click Add Reference.

    The Add Reference dialog box appears.

  2. On the .NET page, select the following assemblies:

    • Microsoft.VisualStudio.Tools.Applications.Hosting.v9.0

    • Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0

    • System.AddIn (version 3.5)

  3. Click OK.

Creating the Host Item Provider

The application needs a class that implements a host item provider. The host item provider enables add-ins to access the host object model. For more information about host item providers, see Exposing Host Objects to Add-Ins.

To create the host item provider

  1. In Solution Explorer, right-click the ShapeAppCSharp project, point to Add on the shortcut menu, and then click Class.

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

  3. Replace the using statements at the top of the code file with the following statements.

    using System;
    using Microsoft.VisualStudio.Tools.Applications.Runtime;
    
  4. Replace the HostItemProvider class with the following code.

    This code does the following things:

    • It derives the HostItemProvider class from the IHostItemProvider interface. All host item providers must implement this interface.

    • The constructor initializes the application field.

    • It implements the GetHostObject method.

    internal class HostItemProvider : IHostItemProvider
    {
        public HostItemProvider(ShapeApp.Application application)
        {
            this.application = application;
        }
    
        public object GetHostObject(Type primaryType, string primaryCookie)
        {
            if (primaryType == typeof(ShapeApp.Application))
            {
                return this.application;
            }
            else
            {
                throw new ArgumentOutOfRangeException("primaryType != " + typeof(ShapeApp.Application));
            }
        }
    
        private ShapeApp.Application application;
    }
    
  5. In Solution Explorer, right-click the ShapeAppCSharp project, and then click Build. Verify that the project builds without errors.

Creating the Type Map Provider

Visual Studio Tools for Applications uses a type map provider to determine how to convert types between the object model of your host application and proxy types used by add-ins. For more information about type map providers, see Mapping Host Types to Proxy Types.

To create the type map provider

  1. In Solution Explorer, right-click the ShapeAppCSharp project, point to Add on the shortcut menu, and then click Class.

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

  3. Replace the HostTypeMapProvider class with the following code. This code defines a HostTypeMapProvider class that implements the ITypeMapProvider interface. For more information about how this code works, see Mapping Host Types to Proxy Types.

    Note

    You can use the Proxy Generation tool (ProxyGen.exe) to automatically generate the type map provider for your application's object model. For the purposes of this walkthrough, you can use the following code. This is the same code that ProxyGen.exe generates if you pass it the executable file for ShapeAppCSharp. For more information, see Mapping Host Types to Proxy Types.

    internal partial class HostTypeMapProvider : Microsoft.VisualStudio.Tools.Applications.Runtime.ITypeMapProvider
    {
        partial void AddCustomTypes();
    
        System.Collections.Generic.Dictionary<System.Type, System.String> typeToCanonicalName = null;
        System.Collections.Generic.Dictionary<System.String, System.Type> canonicalToTypeName = null;
    
        internal HostTypeMapProvider()
        {
            typeToCanonicalName = new  System.Collections.Generic.Dictionary<System.Type, string>();
            canonicalToTypeName = new System.Collections.Generic.Dictionary<string, System.Type>();
    
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventHandler",
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventHandler", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventHandler));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventArgs", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventArgs));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.IShape", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.IShape));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Application", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Application));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeCollection", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeCollection));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingCollection", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingCollection));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationInvalidException", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationInvalidException));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeInvalidException", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeInvalidException));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Document", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Document));
            canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Drawing", 
                typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Drawing));
    
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventHandler), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventHandler");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.AddedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ColorChangedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationChangedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeChangedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.NameChangedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingRemovedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventArgs), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeRemovedEventArgs");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.IShape), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.IShape");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Application), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Application");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeCollection), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.ShapeCollection");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingCollection), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.DrawingCollection");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationInvalidException), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.LocationInvalidException");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeInvalidException), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.SizeInvalidException");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Document), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Document");
            typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Drawing), 
                "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Drawing");
    
            this.AddCustomTypes();
        }
    
        public string GetCanonicalNameForType(System.Type type)
        {
            if (typeToCanonicalName.ContainsKey(type))
            {
                return typeToCanonicalName[type];
            }
            return null;
        }
    
        public System.Type GetTypeForCanonicalName(string canonicalName)
        {
            if (canonicalToTypeName.ContainsKey(canonicalName))
            {
                return canonicalToTypeName[canonicalName];
            }
            return null;
        }
    }
    
  4. In Solution Explorer, right-click the ShapeAppCSharp project, and then click Build. Verify that the project builds without errors.

Adding Structs to the Type Map

ShapeAppCSharp defines several serializable structs that can be used by add-ins. Because ShapeAppCSharp defines its own proxies for these structs, rather than generating proxies for them by using ProxyGen.exe, you must manually add the structs to the type map. For more information, see Creating Proxies for Managed Structs.

To add structs to the type map

  1. In Solution Explorer, right-click the ShapeAppCSharp project, point to Add on the shortcut menu, and then click Class.

  2. Change the name of the class to HostTypeMapProvider.Structs.cs, and click Add.

  3. Replace the HostTypeMapProvider class with the following code. This code defines a partial extension to the HostTypeMapProvider class that you added earlier. This partial class extension defines the AddCustomTypes method, which adds the Color, Point, and Size structs to the type map.

    namespace Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp
    {
        internal partial class HostTypeMapProvider : Microsoft.VisualStudio.Tools.Applications.Runtime.ITypeMapProvider
        {
            partial void AddCustomTypes()
            {
                canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Color", 
                    typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Color));
                canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Point", 
                    typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Point));
                canonicalToTypeName.Add("ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Size", 
                    typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Size));
    
                typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Color), 
                    "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Color");
                typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Point), 
                    "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Point");
                typeToCanonicalName.Add(typeof(Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Size), 
                    "ShapeAppCSharp, Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp.Size");
            }
        }
    }
    
  4. In Solution Explorer, right-click the ShapeAppCSharp project, and then click Build. Verify that the project builds without errors.

Discovering and Loading Add-Ins

To give ShapeAppCSharp the ability to discover and load add-ins, create a class that accesses the add-in programming model API in the .NET Framework. Later in this walkthrough you will use this class to load add-ins when the application starts. For more information about the add-in management API, see Discovering and Loading Add-Ins.

To discover and load add-ins

  1. In Solution Explorer, right-click the ShapeAppCSharp project, point to Add on the shortcut menu, and then click Class.

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

  3. Replace the using statements at the top of the code file with the following statements.

    using System;
    using System.AddIn.Hosting;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel.Design;
    using System.IO;
    using Microsoft.VisualStudio.Tools.Applications.Runtime;
    
  4. Add the following fields and constants to the VstaRunTimeIntegration class. The fields perform the following functions:

    • The application field is an instance of the Application type defined in the ShapeAppCSharp object model. This is the root-level type in the object model.

    • The serviceProvider field is an IServiceProvider that is used to pass the host item provider and type map provider to the add-in.

    • The addInList field is a collection of add-ins that are discovered by ShapeAppCSharp. This collection contains instances of the IEntryPoint interface, which represents the host application's view of an add-in. For more information, see Discovering and Loading Add-Ins.

    • The StartUpClass constant specifies the name of the host item class that ShapeAppCSharp expects to find in add-ins. This is the class that is instantiated when the add-in loads. All add-ins loaded by this version of ShapeAppCSharp are expected to have a class named AppAddIn. For more information about host items, see Creating Project Templates Using the Project Template Generation Tool (Projectgen.exe).

    • The AddInPath constant specifies the add-in installation folder in which ShapeAppCSharp looks for add-ins to load. ShapeAppCSharp searches in %UserProfile%\Documents\ShapeAppCSharp\AppAddIns (Windows Vista) or %UserProfile%\My Documents\ShapeAppCSharp\AppAddIns (Windows XP).

    private Application application;
    private IServiceProvider serviceProvider;
    private List<IEntryPoint> addInList;
    
    private const String StartUpClass = "AppAddIn";
    private static readonly String AddInPath =
        Path.Combine(System.Environment.GetFolderPath(
        System.Environment.SpecialFolder.MyDocuments), @"ShapeAppCSharp\AppAddIns");
    
  5. Add the following constructor to the VstaRunTimeIntegration class. This constructor initializes the addInList field.

    public VstaRunTimeIntegration()
    {
        this.addInList = new List<IEntryPoint>();
    }
    
  6. Add the following method to the VstaRunTimeIntegration class. This method initializes the application field, instantiates the host item provider and type map provider, and then loads all installed add-ins. Later in this walkthrough you will add code that calls this method when ShapeAppCSharp starts.

    internal void Connect(Application application)
    {
        this.application = application;
        this.InstantiateServiceProvider();
        this.LoadAppLevelAddIns();
    }
    
  7. Add the following method to the VstaRunTimeIntegration class. This method instantiates the host item provider and type map provider that you defined earlier, and then adds these objects to a ServiceContainer. Later in this walkthrough, you will expose these services to Visual Studio Tools for Applications by passing the ServiceContainer to the Initialize method of each loaded add-in.

    private void InstantiateServiceProvider()
    {
        if (this.serviceProvider == null)
        {
            IHostItemProvider itemProvider = new HostItemProvider(this.application);
    
            ITypeMapProvider typeMapProvider = new HostTypeMapProvider();
    
            ServiceContainer container = new ServiceContainer();
            container.AddService(typeof(IHostItemProvider), itemProvider);
            container.AddService(typeof(ITypeMapProvider), typeMapProvider);
    
            this.serviceProvider = container;
        }
    }
    
  8. Add the following method to the VstaRunTimeIntegration class. This method searches for files that have the .dll extension in each folder that is immediately under the add-in installation folder, and it attempts to load each file as an add-in assembly. The method assumes that each add-in assembly has the same name as the folder that contains it, and each add-in contains a host item class with the fully qualified name AssemblyName.AppAddIn. Later in this walkthrough, you will load a sample add-in that contains a host item class named ShapeAppCSharpAppAddIn.AppAddIn.

    private void LoadAppLevelAddIns()
    {
        if (!Directory.Exists(VstaRunTimeIntegration.AddInPath))
            return;
    
        string[] addInDirs = Directory.GetDirectories(
            VstaRunTimeIntegration.AddInPath, "*", SearchOption.TopDirectoryOnly);
    
        foreach (string addInDir in addInDirs)
        {
            string addInShortName = Path.GetFileName(addInDir);
            string addInFullName = Path.Combine(addInDir, addInShortName + ".dll");
    
            if (!File.Exists(addInFullName))
                continue;
    
            string startUpClass = addInShortName + "." + VstaRunTimeIntegration.StartUpClass;
    
            this.LoadAddIn(addInFullName, startUpClass);
        }
    }
    
  9. Add the following method to the VstaRunTimeIntegration class. This method performs the following tasks:

    • It uses the FindAddIn method to discover all add-ins that contain a host item that implements the IEntryPoint interface and that have the specified host item class name.

    • It uses the Activate method to load the add-in. This method loads the add-in in a new application domain that is granted full trust, and returns an IEntryPoint object that represents the host application's view of the add-in.

    • It calls the initialization methods of the IEntryPoint object to initialize the add-in.

    private bool LoadAddIn(string addInPath, string startUpClass)
    {
        Collection<AddInToken> addInToken = AddInStore.FindAddIn(
            typeof(IEntryPoint), AddInStoreExtensions.DefaultPipelinePath, addInPath, startUpClass);
    
        if (addInToken.Count == 0)
            return false;
    
        IEntryPoint addIn = addInToken[0].Activate<IEntryPoint>(AddInSecurityLevel.FullTrust);
    
        addIn.Initialize(this.serviceProvider);
        addIn.InitializeDataBindings();
        addIn.FinishInitialization();
    
        this.addInList.Add(addIn);
        return true;
    }
    
  10. In Solution Explorer, right-click the ShapeAppCSharp project and then click Build. Verify that the project builds without errors.

Connecting the Add-in Discovery Code to ShapeApp

To discover and load add-ins when ShapeAppCSharp starts, add code to the Program class to use the VstaRunTimeIntegration class.

To load add-ins when ShapeAppCSharp starts

  1. In Solution Explorer, right-click Program.cs, and then click View Code.

  2. Replace the Main method with the following code. This code creates an instance of the VstaRunTimeIntegration class. The code also calls the Connect method and passes it an instance of the Application class from the ShapeAppCSharp object model.

    static void Main(string[] args)
    {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
    
        Application application = new Application(args);
    
        VstaRunTimeIntegration vstaRunTimeIntegration = new VstaRunTimeIntegration();
        vstaRunTimeIntegration.Connect(application);
    
        System.Windows.Forms.Application.Run(
            application.ApplicationForm);
    }
    
  3. In Solution Explorer, right-click the ShapeAppCSharp project, and then click Build. Verify that the project builds without errors.

Testing the Application

Now you can test ShapeAppCSharp with an add-in to verify that it loads add-ins correctly.

To test the application

  1. Build the ShapeAppBasicCSharp sample, and then build the ShapeAppCSharpAddIns solution that is included with it. This solution implements a basic add-in. For more information, see How to: Build and Run the ShapeAppBasicCSharp Sample.

    This step is necessary to obtain an add-in assembly that you can load in the version of ShapeAppCSharp that you modified in this walkthrough.

  2. In Visual Studio, open the ShapeAppCSharp solution that you modified in this walkthrough.

  3. Press F5.

  4. Verify that ShapeAppCSharp displays a series of messages. These messages are displayed by the add-in you created by building the ShapeAppCSharpAddIns solution. For more information about the tasks performed by the add-in, see How to: Build and Run the ShapeAppBasicCSharp Sample.

  5. Exit ShapeAppCSharp.

Next Steps

If you performed this walkthrough as part of the comprehensive series of walkthroughs for the ShapeAppCSharp sample, return to Walkthrough: Integrating Visual Studio Tools for Applications with ShapeApp.

If you performed this walkthrough as a stand-alone walkthrough, there are several other steps you can perform to complete the process of integrating Visual Studio Tools for Applications into ShapeAppCSharp:

See Also

Concepts

Discovering and Loading Add-Ins

Considerations for Loading Add-Ins

Implementing Host Services

Understanding the Add-in Pipeline in Visual Studio Tools for Applications

Preventing Unexpected Application Failures from Partially Trusted Add-Ins

ShapeApp Samples (Visual Studio Tools for Applications)

Creating Proxies for Managed Structs