防止某些模板在 Normal.dotm 中使用 Word 宏

Prevent Word macro in Normal.dotm for some templates

我有一个包含 AutoNew 宏的 Normal.dotm 文件。 每次使用任何其他模板创建新文档时都会自动执行此宏。

有什么方法可以阻止特定模板的这种自动行为吗? 我有一个 Word VSTO 加载项 运行,所以我可以连接到 Word 的事件,但到目前为止我还没有找到防止这种情况发生的方法。

我知道我可以在以编程方式使用模板时阻止宏执行,例如:

' Disable auto-macros before opening document
wordApplication.WordBasic.DisableAutoMacros(1)

' Open document
newWordDocument = wordApplication.Documents.Open(template.FullName, ConfirmConversions:=False, [ReadOnly]:=True, AddToRecentFiles:=False, Revert:=True)

' Re-enable auto-macros
wordApplication.WordBasic.DisableAutoMacros(0)

但是当用户使用 Windows 资源管理器中的 Word 模板或 Word 中的打开对话框时,此解决方案不起作用,因为在那些情况下我无法在为时已晚之前执行代码。

或者我可以吗? 我希望有人对我有窍门:-)

-

编辑:在尝试不同的解决方案时,我发现了一些可能对处于类似情况下的其他人有所帮助的东西,但不幸的是它对我没有帮助。 似乎如果模板包含一个包含 AutoNew(或 AutoOpen 的模块),则执行该本地宏而不是 Normal.dotm 中的宏。

示例:

Normal.dotm 包含以下宏:

Sub AutoNew()
    MsgBox "Normal.dotm"
End Sub

Test.dotm 包含以下宏:

Sub AutoNew()
    MsgBox "Test.dotm"
End Sub

执行Test.dotm时显示"Test.dotm"信息,不显示"Normal.dotm"信息。
如果从 Test.dotm 模板中删除 AutoNew 宏,消息 "Normal.dotm" 确实会显示。

因此 可以轻松覆盖自动宏。
AutoNewAutoOpen 的本地版本甚至可以是什么都不做的空子。它仍然有效。

这在我的情况下是不可能的,因为我使用的模板是由代码生成的,并且不能包含宏(因为以编程方式向模板添加宏需要用户手动激活选项 "Trust access to the VBA project object model",并且这是我不能要求我的客户为所有用户做的事情。这也是一种安全风险。)

AutoNew 宏中,您可以检查 AttachedTemplate 属性。只有当它是您要应用清洁的模板时,您才能执行相应的宏。

Sub AutoNew()

    If ActiveDocument.AttachedTemplate <> "Normal.dotm" Then
        Exit Sub
    End If

    ' rest of the macro

End Sub

如果您无法控制 Normal.dotm,您可以在自己的模板中放置一个空的 AutoNew 宏。作为Wordonly executes the auto macro in the closest context,Normal.dotm文件中的宏不会被执行。

如果您也无法控制其他模板,您可以告诉您的用户在创建文档时按住 SHIFT 键。这会阻止自动宏的执行。

但是,如果您要求其他系统的所有者找到另一个不依赖于污染 Normal.dotm 文件的解决方案,可能是最好的。

基于问题 "Edit" 部分中描述的变通方法 - 提供带有 "empty" 自动宏的模板 - 可以使用 Open XML SDK 创建一个模板并将 VBA 项目添加到其中以提供此功能。这种方法避免了用户需要允许访问他安装的 VBA 项目。唯一可以触发的 "macro security" 是不允许宏 运行。不过既然客户端用的是宏,反正这应该不是什么大障碍。

最简单的方法是在 Word UI 中创建尽可能多的基本模板,并将其作为起点。

由于您不熟悉 Open XML SDK,下一步是使用基本模板作为起点在 Word UI 中创建一个(或多个)模板,以不同的文件名保存。

然后您可以使用 Open XML SDK Productivity Tool 查看生成这些文件中的任何一个所需的代码,以及使用比较工具,将基本模板转换为派生模板的代码版本。这应该让您开始使用 SDK 及其对象模型。一旦您了解了 Open XML SDK 的工作原理,如果您熟悉 Word 的对象模型,则使用 SDK 提供的对象模型会相对简单,因为已努力使其与"COM" 对象模型可能。

VBA项目可以稍后添加,但您也可以将其包含在基本模板中。那将是最简单的方法。

将此 "starting point" 基本模板作为解决方案的一部分,将其作为解决方案的一部分进行安装。