C# Word interop文档需要时间才能关闭,无法删除临时文件
我正在构建一个C#WinForm应用程序来编辑word文档模板(以及其他功能)。由于我必须插入一些图像,我在计算机的临时文件夹中创建了一个副本(来自数据库请求),并希望在关闭应用程序时删除所有这些文件 关闭Office.Interop.Word的实际文档和应用程序类似乎需要一些时间,我想知道是否有方法在应用程序实际关闭时触发事件或类似事件 以下是我的功能: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
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不再存在,你应该会很好。哦,我以为你在谈论我的自定义临时文件,这实际上是一个聪明的解决方案,谢谢!