Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

Calling Code in Application-Level Add-ins from Other Office Solutions

You can expose an object in your add-in to other solutions, including other Microsoft Office solutions. This is useful if your add-in provides a service that you want to enable other solutions to use. For example, if you have an add-in for Microsoft Office Excel that performs calculations on financial data from a Web service, other solutions can perform these calculations by calling into the Excel add-in at run time.

Applies to: The information in this topic applies to application-level projects for Microsoft Office 2013 and Microsoft Office 2010. For more information, see Features Available by Office Application and Project Type.

There are two main steps in this process:

  • In your add-in, expose an object to other solutions.

  • In another solution, access the object exposed by your add-in, and call members of the object.

You can expose an object in an add-in to the following types of solutions:

  • Visual Basic for Applications (VBA) code in a document that is loaded in the same application process as your add-in.

  • Document-level customizations that are loaded in the same application process as your add-in.

  • Other add-ins created by using the Office project templates in Visual Studio.

  • COM add-ins (that is, add-ins that implement the IDTExtensibility2 interface directly).

  • Any solution that is running in a different process than your add-in (these types of solutions are also named out-of-process clients). These include applications that automate an Office application, such as a Windows Forms or console application, and add-ins that are loaded in a different process.

To expose an object in your add-in to other solutions, perform the following steps in your add-in:

  1. Define a class that you want to expose to other solutions.

  2. Override the RequestComAddInAutomationService method in the ThisAddIn class. Return an instance of the class that you want to expose to other solutions.

At a minimum, the class you want to expose must be public, it must have the ComVisibleAttribute attribute set to true, and it must expose the IDispatch interface.

The recommended way to expose the IDispatch interface is to perform the following steps:

  1. Define an interface that declares the members that you want to expose to other solutions. You can define this interface in your add-in project. However, you might want to define this interface in a separate class library project if you want to expose the class to non-VBA solutions, so that the solutions that call your add-in can reference the interface without referencing your add-in project.

  2. Apply the ComVisibleAttribute attribute to this interface, and set this attribute to true.

  3. Modify your class to implement this interface.

  4. Apply the ClassInterfaceAttribute attribute to your class, and set this attribute to the None value of the ClassInterfaceType enumeration.

  5. If you want to expose the class to out-of-process clients, you might also need to do the following:

The following code example demonstrates an AddInUtilities class with an ImportData method that can be called by other solutions. To see this code in the context of a larger walkthrough, see Walkthrough: Calling Code in an Application-Level Add-in from VBA.

[ComVisible(true)]
public interface IAddInUtilities
{
    void ImportData();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddInUtilities : IAddInUtilities
{
    // This method tries to write a string to cell A1 in the active worksheet. 
    public void ImportData()
    {
        Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet;

        if (activeWorksheet != null)
        {
            Excel.Range range1 = activeWorksheet.get_Range("A1", System.Type.Missing);
            range1.Value2 = "This is my data";
        }
    }
}

When you perform the steps provided above, VBA code can call only the methods that you declare in the interface. VBA code cannot call any other methods in your class, including methods that your class obtains from base classes such as Object.

You can alternatively expose the IDispatch interface by setting the ClassInterfaceAttribute attribute to the AutoDispatch or AutoDual value of the ClassInterfaceType enumeration. If you do this, you do not have to declare the methods in a separate interface. However, VBA code can call any public and non-static methods in your class, including methods obtained from base classes such as Object. In addition, out-of-process clients that use early binding cannot call your class.

If you want to expose a class in your add-in to out-of-process clients, you should derive the class from StandardOleMarshalObject to ensure that out-of-process clients can call your exposed add-in object. Otherwise, attempts to get an instance of your exposed object in an out-of-process client might fail unexpectedly.

This is because all calls into the object model of an Office application must be made on the main UI thread, but calls from an out-of-process client to your object will arrive on an arbitrary RPC (remote procedure call) thread. The COM marshaling mechanism in the .NET Framework will not switch threads, and it will instead attempt to marshal the call to your object on the incoming RPC thread instead of the main UI thread. If your object is an instance of a class that derives from StandardOleMarshalObject, incoming calls to your object are automatically marshaled to the thread where the exposed object was created, which will be the main UI thread of the host application.

For more information about using threads in Office solutions, see Threading Support in Office.

The following code example demonstrates how to override RequestComAddInAutomationService in the ThisAddIn class in your add-in. This example assumes that you have defined a class named AddInUtilities that you want to expose to other solutions. To see this code in the context of a larger walkthrough, see Walkthrough: Calling Code in an Application-Level Add-in from VBA.

private AddInUtilities utilities;

protected override object RequestComAddInAutomationService()
{
    if (utilities == null)
        utilities = new AddInUtilities();

    return utilities;
}

When your add-in is loaded, the Visual Studio Tools for Office runtime calls the RequestComAddInAutomationService method. The runtime assigns the returned object to the Object property of a COMAddIn object that represents your add-in. This COMAddIn object is available to other Office solutions, and to solutions that automate Office.

To call the exposed object in your add-in, perform the following steps in the client solution:

  1. Get the COMAddIn object that represents the exposed add-in. Clients can access all of the available add-ins by using the Application.COMAddIns property in the object model of the host Office application.

  2. Access the Object property of the COMAddIn object. This property returns the exposed object from the add-in.

  3. Call the members of the exposed object.

The way that you use the return value of the COMAddIn.Object property is different for VBA clients and non-VBA clients. For out-of-process clients, additional code is necessary to avoid a possible race condition.

The following code example demonstrates how to use VBA to call a method that is exposed by an add-in. This VBA macro calls a method named ImportData that is defined in an add-in that is named ExcelImportData. To see this code in the context of a larger walkthrough, see Walkthrough: Calling Code in an Application-Level Add-in from VBA.

Sub CallVSTOMethod()
    Dim addIn As COMAddIn
    Dim automationObject As Object
    Set addIn = Application.COMAddIns("ExcelImportData")
    Set automationObject = addIn.Object
    automationObject.ImportData
End Sub

In a non-VBA solution, you must cast the COMAddIn.Object property value to the interface it implements, and then you can call the exposed methods on the interface object. The following code example demonstrates how to call the ImportData method from a different add-in that was created by using the Office developer tools in Visual Studio.

object addInName = "ExcelImportData";
Office.COMAddIn addIn = Globals.ThisAddIn.Application.COMAddIns.Item(ref addInName);
ExcelImportData.IAddInUtilities utilities = (ExcelImportData.IAddInUtilities)addIn.Object;
utilities.ImportData();

In this example, if you try to cast the value of the COMAddIn.Object property to the AddInUtilities class rather than the IAddInUtilities interface, the code will throw an InvalidCastException.

Show:
© 2014 Microsoft