1

我正在开发一个可以(除其他外)用于关闭 Windows 的 MFC 应用程序。这样做时,Windows 当然会将 WM_QUERYENDSESSION 和 WM_ENDSESSION 发送到所有应用程序,包括我的。然而,问题是我的应用程序,作为一些析构函数的一部分,删除了在执行期间使用的某些文件(使用 CFile::Remove)。我有理由相信当应用程序被 Windows 关闭时,会调用析构函数(但这很难确定)。

但是,当 Windows 再次启动时,我偶尔会注意到应该删除的文件仍然存在。即使程序的执行相同(我有一个用于测试的脚本),这种情况也不会始终如一地发生。这使我认为正在发生以下两种情况之一:a) 析构函数未始终被调用,或者 b) Remove 函数返回,但在 Windows 关闭之前文件实际上并未被删除。

到目前为止,我发现的唯一解决方法是,如果我让系统在程序停止后等待关闭大约 10 秒钟,那么文件将被正确删除。这使我相信 b) 可能是这种情况。

我希望有人能够帮助我解决这个问题。

问候莫特

4

3 回答 3

3

一旦您的程序从 中返回WM_ENDSESSION,Windows 可以随时终止它:

如果会话正在结束,此参数为 TRUE;会话可以在所有应用程序从处理此消息返回后的任何时间结束。

如果会话很快结束,那么它可能会在你的析构函数运行之前结束。您必须在从 回来之前WM_ENDSESSION完成所有清理工作,因为无法保证您之后有机会进行清理。

于 2012-01-30T13:52:23.790 回答
0

这里的问题是某些版本的 Windows 报告文件处理操作在实际完成之前已经完成。这不是问题,除非因为某些操作(包括文件删除)将被放弃而触发关机。

我建议您通过强制您的代码等待确认删除文件(让进程查找文件并在文件消失时引发事件)来解决此问题,然后再调用系统关闭。

于 2012-01-30T09:11:45.470 回答
0

如果系统正确关闭(螺母突然断电等),则所有缓存的数据都会被刷新。特别是这包括刷新应该提交文件删除的全局文件描述符表(或在文件系统中调用的任何文件)。

所以问题似乎是用户模式代码没有调用DeleteFile,或者它失败了(无论出于何种原因)。请注意,应用程序(进程)可以通过多种方式退出,但并不总是调用 d'tors。有自动对象在其调用堆栈的上下文中被销毁,此外还有全局/静态对象,它们由 CRT 初始化/清理代码初始化和销毁​​。

以下是终止进程的方法的简短摘要,以及后果:

  • 所有进程线程都按惯例退出(从它们的过程中返回)。操作系统终止没有线程的进程。所有的 d'tors 都被处决了。
  • 一些线程要么通过退出ExitThread要么被杀死TerminateThread。这些线程的自动对象不会被破坏。
  • 进程退出ExitProcess。自动对象不会被破坏,全局可能会被破坏(这发生在 CRT 中使用的 DLL 中)
  • 进程由 终止TerminateProcess。所有的 d'tors 都没有被调用。

我建议您检查是否确实调用了DeleteFile(或那个 wraos),并检查它是否成功。CFile::Remove例如,无论出于何种原因,您都可能两次打开同一个文件

于 2012-01-30T09:14:25.827 回答