VSTO Word与Excel Add-in双向通信问题:COMAddIns仅显示当前Office插件
解决VSTO跨Office应用插件双向通信问题
问题核心
你当前遍历的Globals.ThisAddIn.Application.COMAddIns只能获取当前Office进程内的COM加载项,而Word、Excel是独立的进程,因此无法通过这种方式看到其他Office程序中的插件。要实现跨进程的插件通信,需要结合COM可见对象+跨进程获取Office实例的方案。
解决方案步骤
1. 修正共享接口与服务类的COM配置
共享接口必须标记ComVisible(true)并指定唯一GUID(跨进程COM依赖GUID识别类型),服务类需正确继承StandardOleMarshalObject避免跨进程线程模型冲突,同时在插件启动时将服务实例绑定到COM加载项的Object属性。
// 共享项目中的接口(必须统一GUID) [ComVisible(true)] [Guid("替换为你生成的唯一GUID")] // 用VS工具生成GUID:工具->创建GUID->选择格式5 public interface IInterAddinCommsService { void Notify(); } // Word插件中的服务类 [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [Guid("另一个唯一GUID")] public class WordAddinNotificationService : StandardOleMarshalObject, IInterAddinCommsService { public void Notify() { MessageBox.Show("Word插件收到跨进程通知"); } } // 在Word插件的ThisAddIn_Startup方法中绑定服务实例 private void ThisAddIn_Startup(object sender, EventArgs e) { // 替换为你的Word插件ProgID(可在项目属性->发布->COM互操作中查看) var comAddIn = this.Application.COMAddIns.Item("WordAddin.Connect"); comAddIn.Object = new WordAddinNotificationService(); }
2. 跨进程获取其他Office应用实例并调用插件
通过Marshal.GetActiveObject获取已运行的Office实例,若不存在则启动新实例,然后访问该实例的COMAddIns集合,筛选目标插件并调用接口方法。
public void OnAction(Office.IRibbonControl control, bool IsPressed) { Excel.Application excelApp = null; try { // 尝试获取已运行的Excel实例 excelApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); } catch (COMException) { // 无运行实例时启动新Excel excelApp = new Excel.Application(); excelApp.Visible = true; } // 遍历Excel的COM加载项,筛选目标插件 foreach (Office.COMAddIn addin in excelApp.COMAddIns) { // 替换为你的Excel插件ProgID if (addin.ProgID == "ExcelAddin.Connect") { var service = addin.Object as IInterAddinCommsService; service?.Notify(); break; } } // 释放COM引用(避免内存泄漏,注意不要随意关闭用户的Office实例) Marshal.ReleaseComObject(excelApp); }
3. 双向通信的补充实现
Excel插件端只需复用相同逻辑:获取Word实例,遍历其COMAddIns集合并调用IInterAddinCommsService接口即可完成双向通信。
关键注意事项
- 所有插件的
IInterAddinCommsService接口GUID必须完全一致,否则跨进程无法转换类型 - 服务类必须继承
StandardOleMarshalObject,否则跨进程调用会出现线程模型错误 - 插件ProgID需与项目配置一致,可通过注册表(
HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins)确认 - 处理Office实例时,不要随意调用
Quit()方法,避免意外关闭用户正在使用的Office程序
内容的提问来源于stack exchange,提问作者Teebee15
相关产品推荐
相关产品推荐

