Функции работы с файлами возвращаются, но фактически не фиксируются при завершении работы Windows - PullRequest
1 голос
/ 30 января 2012

Я работаю над приложением MFC, которое может (помимо прочего) использоваться для выключения Windows.При этом Windows, конечно, отправляет WM_QUERYENDSESSION и WM_ENDSESSION всем приложениям, включая мое.Однако проблема в том, что мое приложение, как часть некоторых деструкторов, удаляет определенные файлы (с помощью CFile :: Remove), которые использовались во время выполнения.У меня есть основания полагать, что деструкторы вызываются (но это точно неизвестно), когда приложение закрывается Windows.

Однако, когда Windows запускается снова, я иногда замечаю, что файлыкоторые должны были быть удалены, все еще присутствуют.Это не происходит последовательно, даже когда выполнение программы идентично (у меня есть скрипт для проверки этого).Это заставляет меня думать, что происходит одно из двух: либо а) деструкторы не вызываются последовательно, либо б) функция удаления возвращается, но файл фактически не удаляется до закрытия Windows.

Единственный обходной путь, который я нашел до сих пор, - это то, что если я заставлю систему ждать с выключением в течение приблизительно 10 секунд после остановки моей программы, тогда файлы будут должным образом удалены.Это заставляет меня верить, что б) может иметь место.

Я надеюсь, что кто-то сможет мне помочь с этой проблемой.

С уважением, Морт

Ответы [ 3 ]

3 голосов
/ 30 января 2012

Как только ваша программа вернется с WM_ENDSESSION, Windows может прекратить ее в любое время:

Если сеанс заканчивается, этот параметр имеет значение ИСТИНА; сеанс может завершиться в любое время после того, как все приложения вернулись после обработки этого сообщения.

Если сессия заканчивается быстро, то она может закончиться до запуска ваших деструкторов. Вы должны сделать всю свою очистку до возвращения с WM_ENDSESSION, потому что нет никакой гарантии, что вы получите возможность сделать это позже.

0 голосов
/ 30 января 2012

Если система правильно выключена (гайка внезапно отключилась, и т. Д.), То все кэшированные данные сбрасываются.В частности, это включает очистку глобальной таблицы дескрипторов файлов (или как она называется в вашей файловой системе), которая должна зафиксировать удаление файла.

Таким образом, проблема заключается в том, что код пользовательского режима не вызывает DeleteFile, или это не удается (по какой-либо причине).Обратите внимание, что приложение (процесс) может выйти несколькими способами, в то время как не всегда вызывается d'tors.Существуют автоматические объекты, которые уничтожаются в контексте их стека вызовов, плюс есть глобальные / статические объекты, которые инициализируются и уничтожаются кодом инициализации / очистки CRT.

Ниже приводится краткое описание способов завершения.процесс с последствиями:

  • Все потоки процесса выходят условно (возврат из процедуры).ОС завершает процесс без потоков.Все д'торы исполняются.
  • Некоторые потоки либо выходят через ExitThread, либо уничтожаются TerminateThread.Автоматические объекты этих потоков не пострадали.
  • Процесс завершен ExitProcess.Автоматические объекты не уничтожаются, глобальные могут быть разрушены (это происходит в том случае, если CRT используется в DLL)
  • Процесс завершается TerminateProcess.Все д'торы не называются.

Я предлагаю вам проверить, действительно ли вызывается DeleteFile (или CFile::Remove, который его заключает в себя), и проверить также, если это удалось.Например, вы можете открыть один и тот же файл дважды по любой причине

0 голосов
/ 30 января 2012

Проблема здесь в том, что некоторые версии Windows сообщают, что операции с файлами были завершены до того, как они действительно были выполнены.Это не проблема, если отключение не инициировано, поскольку некоторые операции, включая удаление файла, будут отменены.

Я бы посоветовал вам справиться с этим, заставив свой код ждать подтвержденного удаления файлов (выполнить процесс поиска файлов и вызвать событие, когда они ушли), прежде чем вызывать систему для завершения работы системы..

...