通过代码禁用 COM-Addin

Disable COM-Addin through code

我们公司有 2 个插件,他们在 Excel 内相处不融洽。其中一个插件来自 SAP(例如,无法修改)。另一个是使用Add In Express

开发的本地的

问题仅限于 Excel。当我们尝试从受保护的视图中提取文档时。使用以下代码

ExcelApp.ActiveProtectedViewWindow.Edit()

当我们执行那行代码时,另一个 (SAP) 插件开始抛出访问冲突。

1st error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt
2nd error: Exception from HResult 0x800A03EC

现在我正在尝试解决冲突。但我卡住了。 我找不到另一种方法来成功地将文档从受保护的视图中取出

暂时禁用 SAP 加载项似乎也不起作用。因为 Application.Addins doesn't contain the COM-Addins. And Application.CommAddins 抛出以下错误:

       ExcelApp.COMAddIns   The embedded interop type 'COMAddIns' does not contain a 
       definition for'Microsoft.Office.Interop.Excel._Application' since it was not used 
       in the compiled assembly. Consider casting to object or changing the 'Embed Interop Types' 
       property to true.    

然而 Embed Interop Types 设置为真。

有人有什么想法吗?

备注 禁用 Protected view 不是一个选项。因为它是在公司层面决定的:-(

我已经设法解决了这个问题。感谢 Charles Williams 使用以下代码,我可以 disable/enable 使用 vb.code

某些 COM-Addins

在这种情况下,SapExcelAddIn 是导致我们所有问题的加载项。

For Each certAddin As Object In ExcelApp.COMAddIns
      log("progId:" & certAddin.progId) 'Logging the id of all Com-addins
      If (certAddin.progId.Equals("SapExcelAddIn")) Then
           log("disconnecting:" & certAddin.progId)
           certAddin.Connect = False
      End If
Next

以防万一有人想在 C# 中执行此操作,这里有一些代码可以禁用多个 COM-AddIns,通过数组参数指定名称:

private void TryDisableCommAddIns(Microsoft.Office.Interop.Excel.Application app, string[] addInsToDisable)
        {
            if(addInsToDisable == null)
            {
                return;
            }
            COMAddIns comAddIns = app.COMAddIns;
            foreach (string addInName in addInsToDisable)
            {
                //If you have a logger you could log a debug statement such as: $"Disabling COM AddIn: {addInName}"
                COMAddIn commAddInOrNull = GetCommAddInOrNull(comAddIns, addInName);
                if(commAddInOrNull != null)
                {
                    commAddInOrNull.Connect = false;
                }
            }
        }

        private COMAddIn GetCommAddInOrNull(COMAddIns comAddIns, string addInName)
        {
            try
            {
                return comAddIns.Item(addInName);
            }
            catch (Exception)
            {
                //If you have a logger you could log a debug statement such as: $"No COM AddIn found with name: {addInName}"
                return null;
            }
        }