如何解决Excel VSTO addin

时间:2016-12-15 22:21:07

标签: c# excel com vsto imanage

我们开发了一个用于Excel的VSTO插件,它可以从Web服务器中提取Excel工作表,并允许用户操作工作表上的数据。它适用于文件的本地副本,但我们并不真正关心该副本。但是我们的一些客户已经拥有了" iManage Integration for Office"安装,这些客户经历奇怪的行为。在这种环境中,我们无法取消关闭事件。

更具体地说,如果用户打开我们的某个文件并进行更改,然后关闭该文件,我们的事件处理程序将触发并提示他们保存更改(对服务器上的数据)。如果他们选择取消,或者他们选择保存并且由于某种原因保存失败,我们设置Cancel = true以尝试保持文件打开。通常这很完美。

对于使用iManage的客户,无论如何文件都会关闭。如果我们的代码保存了文件的本地副本,那么文件就会关闭。如果尚未保存本地副本,则在我们的提示之后,用户会从iManage获取另一个提示,询问他们是否要保存文件。从这里,用户可以单击取消,文件保持打开状态。但是用户报告说,在第一次点击“取消”后看到第二个提示是很困惑的。他们不愿意禁用iManage插件。我们希望能够在这种情况下保持文件打开,最好不要看到iManage提示符。

在为我设置的客户端(Excel 2010)的测试环境中工作,我尝试过以下几点:

  • 我尝试在工作簿级别BeforeClose和applicationlevel WorkbookBeforeClose上设置Cancel;两个都没有工作(启用iManage时文件仍然关闭)
  • 我尝试通过在工作簿级别事件处理程序中注册来确保我的WorkbookBeforeClose处理程序最后注册;没有变化
  • 我可以使用iManage功能区手动切换到本地模式,这使一切正常,但我不知道是否/如何通过代码进行更改。
  • 我可以在Globals.ThisAddIn.Application.COMAddIns中找到iManage插件;我尝试设置其Connect = false,但这会产生一个错误,即只有管理员可以连接/断开插件。
  • 我可以在Closing事件期间保存本地文件,然后执行SaveAs创建第二个副本;第二个副本现在处于活动状态,iManage将其关闭;然后我重新打开原始的本地文件。它看起来对用户来说非常好,但后来我对旧文件中的单元格有一堆COM引用,这些都是垃圾。我可以循环并序列化它们并使用新文件重新创建它们,但是编码和运行将非常耗时,所以我首先要寻找其他想法。

有没有办法让文件保持打开状态,而不会让用户做任何额外的事情?

更新

使用iManage 9.3.0.0和Excel 2010,我创建了一个VBA宏,其中引用了Worksite Integration Interfaces Library(Ex)。该事件触发,但文件仍然关闭。如果我没有设置Saved属性,并且我在网格上输入,我总是会收到来自iManage的提示,询问我是否要保存。

Private WithEvents oWS As iManageExtensibility

Private Sub oWS_DocumentBeforeClose2(ByVal Doc As Variant, IgnoreIManageClose As Boolean, Cancel As Boolean)
    IgnoreIManageClose = True
    Cancel = True
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Set oWS = Application.COMAddIns("WorkSiteOffice2007Addins.Connect").Object
    Cancel = True
    ActiveWorkbook.Saved = True
End Sub

1 个答案:

答案 0 :(得分:1)

您无需为Office禁用iManage集成加载项。您的应用程序应该检测到iManage集成加载项的存在,然后处理该加载项自己的等效关闭事件

为此,首先通过检查Excel Application.COMAddins集合并使用ProgID为WorkSiteOffice2003Addins.Connect(Excel 2003或更早版本)获取COM加载项实例来获取iManage加载项的实例或WorkSiteOffice2007Addins.Connect(Excel 2007或更高版本)。

实际上还应该有一个所谓的"向后兼容性"安装的加载项也注册了oUR02k.Connect的ProgID,您可以参考。同样,是否安装它取决于计算机上安装的FileSite / DeskSite的版本。

这一切似乎让您感到困惑,但这是因为加载项多年来发生了变化,所以它取决于iManage客户端的年龄(即FileSite,DeskSite)以及版本办公室你的目标。您可能需要在代码中补偿不同的Excel / iManage客户端版本

获得正确的COM加载项引用后,请检查COMAddin.Object属性。此值表示iManage Office集成加载项的实例

从那里你可以将该对象强制转换为iManageExtensibility

的强类型COM接口

然后您可以挂钩iManage已经被劫持的所有Office应用程序事件(就像您在应用程序中所做的那样)并响应这些事件而不是本机Excel事件。

在您的情况下,您需要监控DocumentBeforeClose2事件。注意角色' 2'在末尾。还有一个名为DocumentBeforeClose的旧事件,但较新的DocumentBeforeClose2具有以下方法签名:

DocumentBeforeClose2(object doc, ref bool ignoreimanageclose, ref bool cancel)

最后,在您的DocumentBeforeClose2事件处理程序中添加用于取消关闭事件和/或iManage关闭事件的业务逻辑。您可以根据需要将ignoreimanageclose和/或cancel布尔值设置为true / false。在这种情况下,doc参数将是Excel工作簿实例,因此如果您愿意,可以安全地将其转换为Excel.Workbook接口

PS:如果您正在针对iManage API进行开发并需要支持,则应考虑购买iManage SDK。该SDK包含各种API,代码示例的帮助,而且我相信它可以让您访问一些开发人员支持。