C# MSWord自动化:保存文件后获取文件内容

C# MSWord自动化:保存文件后获取文件内容,c#,automation,ms-word,C#,Automation,Ms Word,我有一个应用程序,它使用MSWord automation编辑一些文档,在它们保存并关闭word后,我需要抓取修改后的文件并将其放回存储库,只有一种情况下我无法使其工作,那就是 当用户更改文件时,选择关闭word并选择是保存文件 我正在使用两个事件: 保存之前的文档 退出 在退出事件中,我试图从磁盘加载.docx文件,但在这个特定的场景中,我得到了一个IOException,因为该文件仍在使用中,不知何故,我需要等到退出事件处理完毕之后,也就是Word实际关闭并且不再使用该文件的时候 现在我用这

我有一个应用程序,它使用MSWord automation编辑一些文档,在它们保存并关闭word后,我需要抓取修改后的文件并将其放回存储库,只有一种情况下我无法使其工作,那就是 当用户更改文件时,选择关闭word并选择是保存文件

我正在使用两个事件: 保存之前的文档 退出

在退出事件中,我试图从磁盘加载.docx文件,但在这个特定的场景中,我得到了一个IOException,因为该文件仍在使用中,不知何故,我需要等到退出事件处理完毕之后,也就是Word实际关闭并且不再使用该文件的时候

现在我用这个工作

虽然这样做非常难看,但我需要一种方法在处理退出事件后触发事件,或者在word仍在运行时阻止当前线程,或者在保存文档后获取事件,底线是我需要一种干净的方法在保存完文件并关闭word后加载该文件。文档保存会很棒,但似乎不存在

我还试着解开退出处理程序并在退出处理程序上调用word.Quit,这没有什么区别


我也在调查ManualResetEvent或相关类的使用情况,到目前为止,它几乎可以正常工作,但在发出信号后,我仍然需要暂停,以确保word已关闭且文件不再使用

我以前也遇到过同样的问题。在所有COM相关对象上使用ReleaseComObject成功了(即,在Word文档对象和Word.Application对象上)。这样可以确保在销毁COM对象后删除所有脏锁。使用Interop API关闭文档和应用程序。我使用:

   var localWordapp = new Word.Application();
   localWordapp.Visible = false;
   Word.Document doc = null;
   // ...
    if (doc != null)
    {
      doc.Close();
      System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
    }
    localWordapp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(localWordapp);

我过去也遇到过类似的问题。我不认为有什么好的清洁方法,但是与其像上面那样做,不如考虑一下这个(如果你有一个受控的环境,它会适合你)

  • 创建word应用程序
  • 使用与Winword匹配的GetProcesses立即获取进程ID,返回列表中的最后一个进程应该是您要查找的进程。在多用户环境中,这不是100%可靠的
  • word退出后,使用Thread.Sleep循环确保PID不再存在
  • 为自定义操作读取docx

另一个注意事项:当您发现意外异常时,还记得自己清理。否则,可能会有WINWORD.EXE实例在内存中浮动。这一点都不好笑。我没有程序控制word何时关闭,这是一个用户操作,我只是收到退出事件的通知。我在哪里调用doc.Close()?我把它放在我的退出事件处理程序上,我得到了一个丑陋的例外根据这个msdn链接,ReleaseComObject只适用于2003年,它实际上为我所需要的工作,我将发布工作代码,然后用户打开另一个Word文档,该文档将在同一Word实例中打开,当用户关闭您的文件时,Word永远不会退出。事实上,这种解决方案虽然有效,但应该注意,它只在用户实际关闭Word实例的情况下才有效。然而,这是我发现的唯一安全的方法来确保一切都被“释放”。
   var localWordapp = new Word.Application();
   localWordapp.Visible = false;
   Word.Document doc = null;
   // ...
    if (doc != null)
    {
      doc.Close();
      System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
    }
    localWordapp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(localWordapp);