The first step to integrating Visual Studio Tools for Applications into your host application is to create proxies for the application's object model. You can generate these proxies by using the Proxy Generation tool (ProxyGen.exe). ProxyGen.exe converts the type definitions in a COM type library or a managed assembly into proxy code that you can compile into a proxy assembly. The proxy assembly, along with all of the files that are necessary to create an add-in for your application, can then be used to create a project template. For more information about this process, see Creating Project Templates (Visual Studio Tools for Applications).
ProxyGen.exe can also generate code that implements a type map provider for your application. The type map provider is one of the required services that you must implement in your application and expose to Visual Studio Tools for Applications when you load add-ins. For more information, see Mapping Host Types to Proxy Types.
This topic provides the following information:
A proxy is a type that represents the add-in's view of a type in the host object model. Rather than using host types directly, add-in developers instead use proxy types. This layer of abstraction provides a number of benefits, including the ability to modify the object model that your application exposes to add-ins without changing or recompiling the host object model itself.
When add-in developers write code to automate the host application, their add-in projects reference the proxy assembly for the application, and they use the proxy types as if they were the actual host types. However, only a few proxy types contain code that is executed at run time; most proxy types are just blueprints that Visual Studio Tools for Applications uses to call into the actual host types. For more information about how Visual Studio Tools for Applications uses proxies, see Architecture of Generated Proxy Code.
Proxies provide the following benefits for a host application that supports add-ins:
They enable a loose coupling between add-ins and the host application. This provides for versioning, isolation, and resiliency between the host application and add-ins.
They enable you to change the object model that is exposed to add-in developers without modifying the underlying host object model. For example, you might want to map the Count property of a collection in the host object model to a property named Length in the proxy.
Defining the Object Model of the Host Application
Part of the process of creating proxies is defining what part of the application's object model you want to expose to add-ins. You must define the application's object model that is exposed to add-ins. Specifically, you must identify types that you want add-ins to be able to use, and the types that you want to expose as entry points into the object model. An entry point is a proxy type that provides direct access to an object in the object model of the host application, and is instantiated when the host application loads an add-in. For more information, see Defining Entry Points and Other Proxy Changes.
You can expose the entire object model of the application to add-ins, or a subset of the object model. The entry points that you expose to add-ins help to determine the type of add-ins that your application supports. Some of the most common types of add-ins are document-level and application-level add-ins:
A document-level add-in customizes a specific document or file that is hosted by the application. This type of add-in is loaded when the associated document or file opens, and is only accessible while that document or file is open.
Application-level add-ins are available to the entire application. If the application supports documents, then these types of add-ins are available no matter which file or document is open.
If your application supports multithreaded add-ins, you must review your application's object model to make sure that it is thread safe. If the object model is not thread safe, add-ins that call into your application's object model from different threads could cause race conditions.
ProxyGen.exe is a command-line tool that provides an automated way to generate proxies for your application's object model. ProxyGen.exe includes several different command-line arguments, and there are also different versions for different platforms. For more information, see Proxy Generation Tool (ProxyGen.exe).
The typical process of using ProxyGen.exe includes the following steps:
Run ProxyGen.exe with the /l and /o arguments to generate a proxy descriptor file:
The /l argument specifies the COM type library or managed assembly that contains the object model of your application.
The /o argument specifies the name and location of the proxy descriptor file that ProxyGen.exe will generate.
The proxy descriptor file is an XML file that describes all of the types in the object model of the host application. For more information about the contents of the proxy descriptor file, see ProxyGen Descriptor Schema Reference.
For example, the following command generates a proxy descriptor file for an object model that is contained in the file ShapeAppCSharp.exe.
proxygen.exe /l:%SYSTEMDRIVE%\ShapeAppCSharp\ShapeAppCSharp.exe /o:%SYSTEMDRIVE%\ShapeAppCSharp\Proxy\descriptor.xml
In the proxy descriptor file, optionally specify one or more entry points. Also make any other changes that you want to make to the proxy types, such as hiding types so that ProxyGen.exe does not generate proxies for them. For more information, see Defining Entry Points and Other Proxy Changes.
If your application has a managed object model that includes serializable structs, it is recommended that you modify the proxy descriptor file to prevent ProxyGen.exe from generating proxies for the structs. For more information, see Creating Proxies for Managed Structs.
Run ProxyGen.exe with the /i and /c arguments to generate a proxy code file:
The /i argument specifies the full path of the modified proxy descriptor file.
The /c argument specifies the name and location of the proxy code file that ProxyGen.exe will generate.
The proxy code file contains C# code that defines proxy types for all of the types that are described in the proxy descriptor file. For more information about the contents of the proxy code file, see Architecture of Generated Proxy Code.
For example, the following command generates a proxy code file for an object model that is defined in the proxy descriptor file descriptor.xml.
proxygen.exe /i:%SYSTEMDRIVE%\ShapeAppCSharp\Proxy\descriptor.xml /c:%SYSTEMDRIVE%\ShapeAppCSharp\Proxy\shapeapp.cs
The /c argument also generates a code file that implements a type map provider for the host application. This code is intended to be compiled with the host application, not compiled with the proxy assembly. For more information, see Mapping Host Types to Proxy Types.
You can customize the types in the generated proxy code by creating partial class extensions for the types in a separate code file. For example, you can do this if you want to add new members to a proxy type that do not exist in the object model of the host application. All of the generated proxy types are declared using the partial keyword to make this possible.
This step is necessary if the object model of your host application contains managed exceptions that you want add-in developers to be able to catch or throw. Because ProxyGen.exe does not generate all of the proxy exception members for you, you must define the missing members. For more information, see Creating Proxies for Custom Exceptions.
You should sign the proxy assembly with a strong name. This enables you to deploy the assembly in the global assembly cache as part of the host application's installation process. For more information, see Installing the Proxy Assembly With the Host Application.
Compile the proxy code file (and any other code files that contains partial class extensions of the generated proxy types) into an assembly, which is called the proxy assembly.
For a walkthrough that demonstrates this process, see Walkthrough: Creating a Proxy Assembly.
After you build the proxy assembly, you can pass the assembly to the Project Template Generation tool (Projectgen.exe) to create project templates. For more information, see Creating Project Templates (Visual Studio Tools for Applications) and Walkthrough: Creating a Project Template Using the Project Template Wizard.
To enable your customers to create or use add-ins, you must install the proxy assembly with the host application. Typically, you should install the proxy assembly into the global assembly cache during the installation of the host application. This is the easiest way to ensure that Visual Studio Tools for Applications can locate the proxy assembly when it is referenced by an add-in project, or when the host application loads an add-in. For more information, see Deploying the IDE and Runtime.
To install the proxy assembly in the global assembly cache, you must first sign it with a strong name. For information about how to sign an assembly by using Visual Studio, see How to: Sign an Assembly (Visual Studio) in the MSDN Library for Visual Studio 2008. For information about how to sign an assembly by using a command-line tool or a code attribute, see How to: Sign an Assembly with a Strong Name.
Additional Requirements for Visual Basic Add-Ins
If you create Visual Basic project templates for add-in developers to use, you must perform the following additional steps during the installation of the host application:
Copy the proxy assembly to the following folder:
This is a subfolder of the add-in pipeline directory for Visual Studio Tools for Applications. For more information about the pipeline, see Understanding the Add-in Pipeline in Visual Studio Tools for Applications.
Update the Visual Studio Tools for Applications add-in pipeline so that it recognizes the proxy assembly. You can do this by performing either of the following tasks during the installation process:
Run the AddInUtil.exe tool with the following command:
AddInUtil.exe -PipelineRoot:"%CommonProgramFiles%\microsoft shared\VSTA\Pipeline" -Rebuild
AddInUtil.exe is a tool that can be used to register segments of an add-in pipeline. This tool is installed with the .NET Framework 3.5 in the following folder: %SystemRoot%\Microsoft.NET\Framework\v3.5.
For more information about registering segments of an add-in pipeline, see Add-in Discovery.
If you do not perform these steps, the host application cannot load add-ins that are created by using Visual Basic project templates.
For an example of how to perform these steps, refer to the InstallForVB.bat file in the ShapeApp samples. This file is located in the Proxy subfolder of each sample, and it is run automatically when you compile the proxy project. For more information about the ShapeApp samples, see ShapeApp Samples (Visual Studio Tools for Applications).
When you use ProxyGen.exe to generate proxies for your application's object model, keep the following security considerations in mind:
If you use the /f argument to overwrite existing files, ProxyGen.exe overwrites the files completely. ProxyGen.exe does not preserve access control lists (ACLs).
When you run ProxyGen.exe, static constructors in the managed object model might be executed and cause exceptions to be thrown. The static constructors can be executed because ProxyGen.exe does not load the assembly for reflection only.
If you want your host application to load partially trusted add-ins, the following recommendations can help make proxies more secure:
Sign the proxy assembly with a strong name. For more information, see How to: Sign an Assembly with a Strong Name.
If you sign the proxy assembly with a strong name, you must add the AllowPartiallyTrustedCallersAttribute attribute to the proxy assembly to allow partially trusted callers. For more information, see Modifying Proxies for Partially Trusted Add-Ins.
Give the same access rights to the proxy descriptor file as you give to your source code. Because ProxyGen.exe generates source code from the proxy descriptor file, malicious modification of the proxy descriptor file can generate malicious code in the proxy code file.
ProxyGen.exe does not support native 64-bit object models. You must compile your object model using tools that are specific to COM object models and managed object models, as follows:
COM object models. You must use the Microsoft Interface Definition Language (MIDL) compiler to generate a 32-bit type library. Because OLE automation types are 32-bit/64-bit portable, the generated proxy file will work with a native 64-bit host application. For more information, see the Microsoft Interface Definition Language (MIDL): 64-Bit Porting Guide.
Managed object models. You must compile a 32-bit version of your object model using the CorFlags Conversion Tool (CorFlags.exe) from the Windows Software Development Kit (SDK).