C# Word interop文档需要时间才能关闭,无法删除临时文件

C# Word interop文档需要时间才能关闭,无法删除临时文件,c#,winforms,ms-word,office-interop,C#,Winforms,Ms Word,Office Interop,我正在构建一个C#WinForm应用程序来编辑word文档模板(以及其他功能)。由于我必须插入一些图像,我在计算机的临时文件夹中创建了一个副本(来自数据库请求),并希望在关闭应用程序时删除所有这些文件 关闭Office.Interop.Word的实际文档和应用程序类似乎需要一些时间,我想知道是否有方法在应用程序实际关闭时触发事件或类似事件 以下是我的功能: private void CloseDocument() { if (_doc != null) { _do

我正在构建一个C#WinForm应用程序来编辑word文档模板(以及其他功能)。由于我必须插入一些图像,我在计算机的临时文件夹中创建了一个副本(来自数据库请求),并希望在关闭应用程序时删除所有这些文件

关闭Office.Interop.Word的实际文档和应用程序类似乎需要一些时间,我想知道是否有方法在应用程序实际关闭时触发事件或类似事件

以下是我的功能:

private void CloseDocument()
{
    if (_doc != null)
    {
        _doc.Close();
        _doc = null;
    }

    if (_appClass != null)
    {
        _appClass.Quit();
        _appClass = null;
    }

    File.Delete(tempFileName);

    foreach (string path in _imagePaths)
    {
        File.Delete(path);
    }
}
此函数绑定到
OnHandleDestroyed
事件。不幸的是,当文档包含一组图像时,
\u doc
\u appClass
对象实际关闭似乎需要一些时间,引导程序抛出
System.IO.IOException
进程无法访问文件“C:\Users\***\AppData\Local\Temp\alr1snsc.png”,因为它正被另一个进程使用。


当文档或应用程序类正确关闭时,是否有任何方法可以实际触发函数?请注意,如果我在尝试删除文件之前插入睡眠,一切正常,这就是为什么我得出结论,这确实是关于正确关闭文档的问题。

这是Word的常见问题。在Word对象模型中,没有任何事件可以通知何时释放了文件锁。(然而,我觉得奇怪的是,这将适用于图像文件,通常,我只将此问题与Word文件和链接内容联系起来。)

一件非常重要的事情是,代码显式地释放COM对象并运行GC。如果不发生这种情况,那么在调用应用程序超出范围(退出并清除)之前,不会释放文件锁。问题中的代码似乎释放了对象,但它不会进行垃圾收集。有关示例,请参见

通常,解决此问题的策略是在应用程序下次运行时检查这些文件,然后将其删除

另一种可能是在打开文档时检查是否存在相关的“temp”文件。这将与文档位于同一文件夹中,文件名以波浪号(
~
)开头。当它从文件夹中消失时,文件锁应该消失。因此,对其进行循环检查是可行的


我怀疑Windows API(甚至.NET Framework)可能提供了检测文件锁的功能…

这是Word的常见问题。在Word对象模型中,没有任何事件可以通知何时释放了文件锁。(然而,我觉得奇怪的是,这将适用于图像文件,通常,我只将此问题与Word文件和链接内容联系起来。)

一件非常重要的事情是,代码显式地释放COM对象并运行GC。如果不发生这种情况,那么在调用应用程序超出范围(退出并清除)之前,不会释放文件锁。问题中的代码似乎释放了对象,但它不会进行垃圾收集。有关示例,请参见

通常,解决此问题的策略是在应用程序下次运行时检查这些文件,然后将其删除

另一种可能是在打开文档时检查是否存在相关的“temp”文件。这将与文档位于同一文件夹中,文件名以波浪号(
~
)开头。当它从文件夹中消失时,文件锁应该消失。因此,对其进行循环检查是可行的


我怀疑Windows API(甚至.NET Framework)可能提供了一个检测文件锁的功能…

没有内置的方法来完成您想要做的事情。尽管这是一个普遍的需求,微软还没有解决它。因此,有两种常见的黑客可以实现这一点

1) 在循环中检查临时文件。一旦它消失,你可以删除你的文件

string fileName = "~" + <YourDocumentFileName>
                do
                {

                } while (File.Exists(fileName));

没有内在的方式来做你想做的事情。尽管这是一个普遍的需求,微软还没有解决它。因此,有两种常见的黑客可以实现这一点

1) 在循环中检查临时文件。一旦它消失,你可以删除你的文件

string fileName = "~" + <YourDocumentFileName>
                do
                {

                } while (File.Exists(fileName));

第二个选项不起作用,因为_doc已经关闭,理论上是这样的,但第一个选项应该可以做到,我只是把它放在一个单独的线程中。@TmZn临时文件将保持在原来的位置,直到实际文件完成写入并关闭。也就是说,如果我打开了一个名为MyDoc.docx的文件,就会有一个临时文件~MyDoc.docx。在MyDoc.docx关闭并释放其他文件上的所有锁之前,此文件将一直存在。所以,如果你一直循环到~MyDoc不再存在,你应该会很好。哦,我以为你在谈论我的自定义临时文件,这实际上是一个聪明的解决方案,谢谢!第二个选项不起作用,因为_doc已经关闭,理论上是这样的,但第一个选项应该可以做到,我只是把它放在一个单独的线程中。@TmZn临时文件将保持在原来的位置,直到实际文件完成写入并关闭。也就是说,如果我打开了一个名为MyDoc.docx的文件,就会有一个临时文件~MyDoc.docx。在MyDoc.docx关闭并释放其他文件上的所有锁之前,此文件将一直存在。所以,如果你一直循环到~MyDoc不再存在,你应该会很好。哦,我以为你在谈论我的自定义临时文件,这实际上是一个聪明的解决方案,谢谢!