2012-01-30 2 views
1

Windows를 종료하는 데 사용할 수있는 MFC 응용 프로그램에서 작업하고 있습니다. 이렇게하면 Windows는 물론 WM_QUERYENDSESSION 및 WM_ENDSESSION을 모든 응용 프로그램에 보냅니다. 그러나 문제는 일부 소멸자의 일부인 내 응용 프로그램이 실행 중에 사용 된 특정 파일 (CFile :: Remove 포함)을 삭제한다는 것입니다. 응용 프로그램이 Windows에 의해 닫힐 때 소멸자가 호출된다고 믿을만한 이유가 있습니다.파일 작업 함수는 반환되지만 Windows가 종료 될 때 실제로 커밋되지 않습니다.

그러나 Windows가 다시 시작되면 삭제할 것으로 예상되는 파일이 계속 존재 함을 알게됩니다. 이것은 프로그램의 실행이 동일 할 때조차 일관되게 발생하지 않습니다 (테스트를위한 스크립트가 있습니다). 이것은 두 가지 중 하나가 발생하고 있다고 생각하게 만듭니다. a) 소멸자가 계속 호출되지 않았거나 b) Remove 함수가 반환되지만 Windows가 종료되기 전에 파일이 실제로 삭제되지 않습니다.

내가 지금까지 발견 한 유일한 해결 방법은 내 프로그램이 중지 된 후 약 10 초 동안 시스템을 종료 할 때 파일이 제대로 삭제된다는 것입니다. 이것은 내가 b)가 그럴 수 있다고 믿게합니다.

누군가가이 문제를 해결할 수 있기를 바랍니다. 여기

감사 모트

+0

Mort, 스택 오버플로 환영합니다. 코드를 게시 할 때 솔루션을 제안하면 더 많은 진전이 이루어질 수 있습니다. 어떤 경우라도 실제로 실행되는 코드 경로가 실제로 유효한지 확인하기 위해 로깅 메커니즘 (또는 ETW 포인트)을 갖고 있습니까? CFile :: Remove는 DeleteFile을 호출하고 실패 할 경우 예외를 throw 할 수 있습니다. (내 말 뜻을보기 위해 소스를 살펴보십시오.) 프로그램이 잡히지 않는 예외에서 종료 될 수 있습니까? – selbie

+0

답장을 보내 주셔서 감사합니다. 우선, 나는 CFile :: Remove에 의해 던져진 예외를 다룬다. 그러나 나는 이것이 실제로 일어나는 것을 아직 보지 못했다. – Mort

+0

또한 로깅을 추가했습니다. 다른 두 가지 동일한 실행, 즉 파일이 삭제 된 위치와 그렇지 않은 위치를 비교하면 후자의 경우 로그 파일이 끝까지 잘리는 것을 볼 수 있습니다. 예. 두 로그 파일은 특정 지점까지 동일하며, 그 다음에 파일이 삭제되지 않은 인스턴스의 로그가 중지됩니다 (이 경우 관련 개체의 소멸자는 기록되지 않습니다). 따라서 소멸자가 호출되는지 또는 제거 함수가 성공하거나 실패 하는지를 알 수는 없습니다. – Mort

답변

3

는 Windows가 언제든지 종료 할 수 있습니다 어떤 이유에서 두 번 같은 파일을 열 수 있습니다 : 세션이 종료되고

경우,이 매개 변수가 TRUE; the session can end any time 모든 응용 프로그램이이 메시지 처리에서 반환 된 후.

세션이 빨리 종료되면 소멸자가 실행되기 전에 종료 될 수 있습니다. WM_ENDSESSION에서 돌아 오는 전에을 반환해야합니다. 이후에 할 수있는 보장이 없기 때문에 청소를해야합니다.

0

문제는 그들이 실제로 있기 전에 다시 윈도우 보고서의 일부 버전의 해당 파일 처리 작업이 완료된 것입니다. 파일 삭제를 포함하여 일부 작업이 중단 될 때 종료가 트리거되지 않으면 문제가되지 않습니다.

시스템 종료를 요청하기 전에 코드가 파일을 삭제할 때까지 기다렸다가 (파일을 찾은 다음 파일을 찾은 다음 이벤트가 발생하는 경우) 코드를 강제 실행하여이 문제에 대처할 것을 제안합니다.

+0

이상한 소리가납니다. 즉, 윈도우에 버그가 있다는 것입니다.하지만 종료시 파일 작업을 플러시하지 않습니다. – valdo

+0

이것은 내가 생각할 수 있다고 생각했던 것이었고, 잠시 (InitiateSystemShutdownEx를 사용하여 타임 아웃을 사용하여) Windows를 종료 한 채로 있으면 파일이 항상 삭제된다는 사실에 의혹이 강해졌습니다. 이 시간을 줄이면 파일이 삭제되지 않을 가능성이 높아집니다. – Mort

0

시스템이 올바르게 종료 된 경우 (너트가 갑자기 정전되는 경우) 캐시 된 모든 데이터가 삭제됩니다. 특히 이것은 파일 삭제를 커밋해야하는 전역 파일 설명자 테이블 (또는 파일 시스템에서 호출 된 모든 것)을 비우는 것을 포함합니다.

그래서 문제는 사용자 모드 코드가 DeleteFile을 호출하지 않거나 (이유가 무엇이든) 실패하는 것 같습니다. 응용 프로그램 (프로세스)이 종료 될 수있는 방법에는 여러 가지가 있지만 항상 그런 것은 아닙니다. 호출 스택의 컨텍스트에서 파손되는 자동 객체와 CRT 초기화/정리 코드에 의해 초기화되고 파괴되는 전역/정적 객체가 있습니다.

  • 모든 프로세스 스레드 종료 통상적으로 (그 과정에서 귀국일) :

    다음은 짧은 결과로, 프로세스를 종료하는 방법을 요약 한 것입니다. OS는 스레드가없는 프로세스를 종료합니다. 모든 도둑이 처형됩니다.

  • 일부 스레드는 ExitThread을 통해 종료하거나 TerminateThread에 의해 종료됩니다. 이러한 스레드의 자동 개체는 디 구성되지 않습니다.
  • 프로세스가 ExitProcess에서 종료되었습니다. 자동 개체가 파괴되지 않고 전역이 파괴 될 수 있습니다 (CRT에서 발생하는 문제는 DLL에서 사용됨).
  • 프로세스가 TerminateProcess으로 종료됩니다. 모든 전화는 호출되지 않습니다.

나는 당신이 DeleteFile (를 wraos 또는 CFile::Remove)가 참이라고되어 ​​있는지 확인하고 성공하면 또한 확인하시기 바랍니다. 예를 들어 당신은 당신의 프로그램이 WM_ENDSESSION에서 반환되면

관련 문제