对 VBA 项目的编程访问不受信任(勾选选项,Word 2013)

Programmatic access to the VBA project is not trusted (Option is ticked, Word 2013)

详情

症状

当我尝试在插件的 Startup 事件期间将 VBA 模块注入用户的 Normal.dotm 模板时,我收到 VBA project is not trusted 错误,即使选项被勾选。当我尝试从模板中获取 VBProject 对象时会发生这种情况:

Private Sub ThisAddIn_Startup() Handles Me.Startup
    Dim template as Word.Template = GetNormalTemplate()
    If template IsNot nothing Then
        Dim vbProj = template.VBProject 'Error thrown here
    End If
End Sub

这仅在勾选 General 选项 Show the start screen when this application starts 时发生。

由于某些原因,即使在 splash 屏幕期间加载了普通模板,VBProject 在 start 屏幕上也不可用直到您实际显示文档(空白或其他)。

结果

我设法在 WindowActivate 事件第一次触发时通过 运行 代码实现了我的目标,而不是在加载项的 Startup 事件期间:

Property hasInjectedVba As Boolean = False
Private Sub WindowHasActivated() Handles Application.WindowActivate
    If Not hasInjectedVba Then
        Try
            injectVba()
            hasInjectedVba = True
        Catch ex As Exception
            'handle the something that went wrong
        End Try
    End If
End Sub

总结
如果您尝试 安全地 执行此操作,Cindy 提出了一些非常好的观点,最重要的是 The security measure not allowing programmatic access to VB projects can remain in-place 如果您使用插件模板 - 这完全避免了问题。

与其将代码注入用户的 Normal.dotm,不如考虑创建一个模板 (*.dotm),专门用于与您的加载项交互。

除了 COM 加载项(VSTO 利用的技术)外,Word 还支持 "template add-ins"。这些可以安装在 Word 启动文件夹中,以便 Word 始终自动加载它们,或者您可以选择让您的加载项显式加载(和卸载)它。

在 Word 对象模型中,这是 Addins 集合。它反映了 Word UI.

中的对话框 "Templates and add-ins"

除了一些 "Auto" 宏外,"add-in template" 中的任何代码(和 RibbonXML 扩展)的行为都与 Normal.dotm 中的代码相同。

使用加载项模板代替 Normal.dotm 的优势:

  • 如果 Normal.dotm 损坏或更换它不会影响您的代码
  • 您不需要在每次启动时都进行代码检查 Normal.dotm 中是否存在修改,如果不存在则恢复它
  • 不允许以编程方式访问 VB 项目的安全措施可以保留在原地
  • 您不必担心 Word 崩溃或用户多次登录时可能发生的臭名昭著的 "Normal.dotm is locked by another process"
  • 代码被保护不被用户修改
  • 如果您需要更改代码,更易于维护
  • 可能,您可以在网络位置使用单个共享模板进行管理