1
votes

I'm currently developing a VSTO Word Document-Level addin, and a WPF app. The WPF app uses the classes and methods in the Microsoft.Office.Interop.Word.dll assembly to open the Word DOCX file associated with the Document-Level addin. My WPF app needs to communicate with the VSTO Word Document-Level addin to update the document while the DOCX file is open.

I found an article on the web called VSTO Add-ins, COMAddIns and RequestComAddInAutomationService that shows how to communicate to an Excel Addin from VBA. I thought I could use the same ideal to make my WPF app communicate with my VSTO Word Document-Level addin.

The article describes how to override the RequestComAddInAutomationService method in the add-in class.

public partial class ThisAddIn
{
    private AddinUtilities addinUtilities;

    protected override object RequestComAddInAutomationService() 
    {
        if (addinUtilities == null)
        {
            addinUtilities = new AddinUtilities();
        }

        return addinUtilities;
    } 
}

My VSTO Word Document-Level addin doesn't have a ThisAddin class that inherits from the Microsoft.Office.Tools.AddinBase class. It has a ThisDocument class that inherits from the Microsoft.Office.Tools.Word.DocumentBase class. And the DocumentBase class doesn't contain a method called RequestComAddInAutomationService that can be overridden.

So the question is, is it possible for another app to communicate with a VSTO Word Document-Level addin? And if so can you please show me a C# example of how to do it?

1
THIS may be of interest to youuser2140173

1 Answers

1
votes

The VSTO technology doesn't have any tools that expose code in a document-level customization to outside code, such as an Add-in. It apparently is possible, although I've never tried it. There's a discussion on MSDN, in the VSTO forum, that outlines the steps involved.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/10decfd2-b1b6-4bf2-aa99-16c1f08b9159/call-code-in-doclevel-assembly-from-addin?forum=vsto

I've copied McLean Schofields "Answer" to the question below as there's no knowing when the link may break.

That discussion mentions a sample from Andrew Whitechapel. That sample is no longer available, but his blog article that relates to it is:

http://blogs.msdn.com/b/andreww/archive/2008/03/20/integrating-doc-level-and-add-in-solutions.aspx.

Quote from McLean Schofield in MSDN post Dec. 16 2008:

"In the sample, .NET remoting is used to send the IDocumentCommands object from the document-level customization to the application-level add-in, and to transmit calls that the add-in makes on this object to the document customization. .NET remoting comes into play in the definition of the DocumentCommands class in the document customization. This class implements the IDocumentCommands interface, which is how the add-in views this object, and it also derives from MarshalByRefObject, which enables it to be transmitted to the add-in (across application domains) via .NET remoting.

In a nutshell, this is how the sample works: 1.When the add-in loads, its override of the RequestComAddInAutomationService method exposes an IAddInCommands object to the document customization (and to any other Office solution that can access the Application.COMAddIns collection). This feature of add-ins is documented in more detail in Calling Code in Application-Level Add-ins from Other Office Solutions. When you expose an object in an add-in in the way described in this topic, you enable the object to be accessed by other Office solutions via COM interop. 2.When the document customization starts, code in ThisDocument_Startup gets the COMAddIn object that represents the add-in, and calls the RegisterDocument method exposed by the add-in to send it an instance of the IDocumentCommands object defined by the document customization. Because the instance it sends derives from MarshalByRefObject, this object is automatically sent to the add-in via .NET Remoting. For more information about .NET remoting, see Remotable and Non-remotable Objects. 3.Now the communication infrastructure is set up. When the user clicks on the actions pane button in the document customization, the btnCallAddIn_Click event handler uses the exposed IAddInCommands object to call the InsertText method defined in the add-in - this call uses the "standard CLR COM interop" that Andrew refers to. When the user clicks on the Ribbon button created by the add-in, the btnCallDocument_Click event handler uses the exposed IDocumentCommands object to call the InsertText method defined in the document customization - this call relies on .NET remoting.

Defining interfaces that are referenced by both the document-level customization and the application-level add-in is necessary in this scenario. For the add-in to call a method defined by the document customization (or vice versa), the solutions need a common "contract" object that defines the method. In order for both solutions to use the same object, the object must implement an interface that is defined in an assembly that both solutions reference. If you were to instead define this interface separately, once in the customization and again in the add-in, these interfaces would be viewed at run time as separate types, and the communication wouldn't work."