如何使.NET应用程序与VSTO Word文档级加载项进行通信

本文关键字:加载项 通信 文档 Word NET 何使 应用程序 VSTO | 更新日期: 2023-09-27 18:21:25

我目前正在开发一个VSTO Word文档级插件和一个WPF应用程序。WPF应用程序使用Microsoft.Office.Interop.Word.dll程序集中的类和方法来打开与文档级加载项关联的Word DOCX文件。当DOCX文件打开时,我的WPF应用程序需要与VSTO Word文档级别加载项通信以更新文档。

我在网上找到了一篇名为VSTO加载项、COMAddIns和RequestComAddInAutomationService的文章,介绍了如何从VBA与Excel加载项通信。我想我可以用同样的理想来让我的WPF应用程序与我的VSTO Word文档级插件进行通信。

本文描述了如何重写外接程序类中的RequestComAddInAutomationService方法。

public partial class ThisAddIn
{
    private AddinUtilities addinUtilities;
    protected override object RequestComAddInAutomationService() 
    {
        if (addinUtilities == null)
        {
            addinUtilities = new AddinUtilities();
        }
        return addinUtilities;
    } 
}

我的VSTO Word文档级加载项没有从Microsoft.Office.Tools.AddinBase类继承的ThisAddin类。它有一个继承自Microsoft.Office.Tools.Word.DocumentBase类的ThisDocument类。并且DocumentBase类不包含可以重写的名为RequestComAddInAutomationService的方法。

所以问题是,另一个应用程序是否有可能与VSTO Word文档级加载项进行通信?如果是的话,你能给我看一个C#的例子吗?

如何使.NET应用程序与VSTO Word文档级加载项进行通信

VSTO技术没有任何工具可以将文档级自定义中的代码公开给外部代码,例如外接程序。这显然是可能的,尽管我从未尝试过。MSDN上的VSTO论坛上有一个讨论,概述了所涉及的步骤。

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

我已经复制了McLean Schofields对下面问题的"答案",因为不知道链接何时会断开。

该讨论提到了Andrew Whitechapel的一个样本。这个样本已经不可用了,但他与之相关的博客文章是:

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

引用McLean Schofield在MSDN上的文章2008年12月16日:

"在示例中,.NET远程处理用于将IDocumentCommands对象从文档级自定义项发送到应用程序级外接程序,并将外接程序对此对象的调用传输到文档自定义项。.NET远程处理在文档自定义项中DocumentCommands类的定义中发挥作用。此类实现IDocumentCommands接口,这是外接程序查看此对象的方式,它还派生自MarshalByRefObject,使它能够通过.NET远程处理传输到外接程序(跨应用程序域)。

简而言之,这就是示例的工作方式:1.加载外接程序时,它对RequestComAddInAutomationService方法的覆盖将IAddInCommands对象公开给文档自定义(以及可以访问Application.COMAddIns集合的任何其他Office解决方案)。外接程序的这一功能在"从其他Office解决方案调用应用程序级外接程序中的代码"中有更详细的说明。按照本主题中所述的方式在外接程序中公开对象时,其他Office解决方案可以通过COM互操作访问该对象。2.当文档自定义开始时,ThisDocument_Startup中的代码获取表示外接程序的COMAddIn对象,并调用外接程序公开的RegisterDocument方法,向其发送文档自定义定义的IDocumentCommands对象的实例。因为它发送的实例派生自MarshalByRefObject,所以该对象会通过.NET远程处理自动发送到外接程序。有关.NET远程处理的详细信息,请参阅可远程处理和不可远程处理对象。3.现在通信基础设施已经建立。当用户单击文档自定义中的操作窗格按钮时,btnCallAddIn_Click事件处理程序使用公开的IAddInCommands对象来调用外接程序中定义的InsertText方法-此调用使用Andrew引用的"标准CLR COM互操作"。当用户单击外接程序创建的功能区按钮时,btnCallDocument_Click事件处理程序使用公开的IDocumentCommands对象来调用文档自定义中定义的InsertText方法-此调用依赖于.NET远程处理。

在这种情况下,定义文档级自定义和应用程序级外接程序都引用的接口是必要的。为了让外接程序调用文档自定义定义的方法(反之亦然),解决方案需要一个定义该方法的通用"约定"对象。为了使两个解决方案都使用同一个对象,该对象必须实现在两个方案都引用的程序集中定义的接口。如果您单独定义这个接口,一次在自定义中,另一次在外接程序中,这些接口在运行时将被视为单独的类型,通信将不起作用。"