【问题标题】:MS Word Application Quit Event only firing after second time on Word 2007MS Word 应用程序退出事件仅在 Word 2007 上第二次后触发
【发布时间】:2019-08-30 01:43:08
【问题描述】:

每当特定的 MS Word 应用程序实例退出时,我都需要运行一些逻辑。我使用Microsoft.Office.Interop.Word 来:

  1. 创建我的 Word 应用程序实例
  2. 打开一个文档
  3. 选择一些表单域并更改其文本。
  4. 使 Word 应用程序对用户可见以进行交互。
  5. 在用户交互之后,使用Microsoft.Office.Interop.Word.ApplicationEvents4_Event.Quit 事件处理程序捕获退出事件(当用户退出 Word 时)

我正在使用现代机器开发运行 Office 365(Word 16)的应用程序,在该应用程序上触发事件在第一次尝试时没有出现问题。

但是,在运行 Word 2007 的旧机器上,必须部署我正在开发的程序,该事件仅在第二次创建实例后触发。我觉得很奇怪。

这是我的代码。它在 WinForms btn_click 事件中运行。

//instantiate word application
Microsoft.Office.Interop.Word.Application wordApp = null;
wordApp = new Microsoft.Office.Interop.Word.Application();

//open document
Document wordDoc = wordApp.Documents.Open(WordDocumentPath);
//use a dictionary to fill in the form fields
foreach (KeyValuePair<string, string> fieldValue in FieldsValues)
{
    FormField formField = wordDoc.FormFields[fieldValue.Key];
    formField.Select();
    formField.Result = fieldValue.Value;
}

//make Word UI visible and bring to front
wordApp.Visible = true;
wordDoc.Activate();
wordApp.Activate();

//handle quit event
ApplicationEvents4_Event wordEvents = wordApp;
wordEvents.Quit += OnWordQuit;

OnWordQuit() 方法上我会运行一些逻辑,但现在我只使用消息框

//only runs on Word 2007 when I click the button for the second time
private void OnWordQuit()
{
    MessageBox.Show("OnWordQuit");
}

【问题讨论】:

    标签: c# .net winforms ms-word office-interop


    【解决方案1】:

    我想问题在于您将事件处理程序 OnWordQuit 附加到局部变量 wordEventsQuit 属性,该属性仅存在于您的 btn_click 事件处理程序中。

    一旦btn_click 事件处理程序完成,此变量就会超出范围。那是在 Word 真正关闭之前很久,wordEvents.Quit 事件处理程序可能会进入垃圾箱,并且没有什么可以对此做出反应。

    尝试在您的 Form 类上声明 ApplicationEvents4_Event wordEvents 字段并将事件处理程序分配给该字段。您的代码应该这样更改:

    //ApplicationEvents4_Event wordEvents = wordApp;
    this.wordEvents.Quit += OnWordQuit;     //  field or property ApplicationEvents4_Event wordEvents should be defined on the form class
    

    通过这种方式,您将确保只要您的表单打开,OnWordQuit 就会继续存在...

    【讨论】:

    • 事件的范围确实是问题所在。不知何故,在 Office 2007 的上下文中,事件在第一次被收集但接下来被保留。一个后续问题:我仍然在我的btn_click 处理程序中声明我的所有 COM 对象(单词应用程序和文档)。我只在捕获到异常时才费心释放 COM 对象,因为我相信用户可以自己退出应用程序,因为他可以访问 UI。我应该在 OnWordQuit 中显式释放 COM 对象吗?还是多余的?
    • 在类似情况下的代码中,我不会显式处理 COM 对象。我只是注意所有对Word.Application 对象的引用在不再需要时立即转向null,并相信垃圾收集器会完成其余的工作。虽然可能显式处置会更快释放资源并获得一些性能提升......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多