C++/Win32: How to wait for a pending delete to complete

前端 未结 13 940
不思量自难忘°
不思量自难忘° 2020-11-30 03:20

Solved:

  • Workable solution: sbi\'s answer
  • Explanation for what really happens: Hans\'s answer
  • Explanation for why OpenFile do
相关标签:
13条回答
  • 2020-11-30 03:33

    Silly suggestion - since it fails so infrequently, simply wait some milliseconds on failure and try again.

    Or, if latency is important, switch to another file name, leaving the old file to be deleted later.

    0 讨论(0)
  • 2020-11-30 03:36

    According to [1], you could use NtDeleteFile to avoid the asynchronous nature of DeleteFile. Also [1] gives some details on how DeleteFile works.

    Unfortunately the official documentation on NtDeleteFile [2] doesn't mention any particular details on this issue.

    [1] Undocumented functions of NTDLL

    [2] ZwDeleteFile function

    0 讨论(0)
  • 2020-11-30 03:37

    There are other processes in Windows that want a piece of that file. The search indexer is an obvious candidate. Or a virus scanner. They'll open the file for full sharing, including FILE_SHARE_DELETE, so that other processes aren't heavily affected by them opening the file.

    That usually works out well, unless you create/write/delete at a high rate. The delete will succeed but the file cannot disappear from the file system until the last handle to it got closed. The handle held by, say, the search indexer. Any program that tries to open that pending-delete file will be slapped by error 5.

    This is otherwise a generic problem on a multitasking operating system, you cannot know what other process might want to mess with your files. Your usage pattern seems unusual, review that first. A workaround would be to catch the error, sleep and try again. Or moving the file into the recycle bin with SHFileOperation().

    0 讨论(0)
  • 2020-11-30 03:39

    On Windows Vista/Windows 7 there is DeleteFileTransacted which deletes a file using transactions which ensures they are deleted (flushes file buffers, etc.). For Windows XP compatibility this is not an option though.

    Another idea how this might be done is use OpenFile() with the flag OF_CREATE which sets the length to zero if the file exists or creates it if it doesn't and then to call FlushFileBuffers on the file handle to wait for this operation (making the file zero length) to complete. On completion, the file is of size 0 and then simply call DeleteFile.

    You can later test if the file exists or if it has zero-length to treat it the same way.

    0 讨论(0)
  • 2020-11-30 03:41

    I actually had the same issue while using the LoadLibrary(path). I couldn't delete the file in path.

    The solution was to "close the handle" or use the FreeLibrary(path) method.

    NOTE: Please read the "Remarks" on MSDN regarding the FreeLibrary().

    0 讨论(0)
  • 2020-11-30 03:41

    The best answer was given by sbi, but in the interest of completeness, some people might also want to know about a new way now available from Windows 10 RS1/1603.

    It involves calling the SetFileInformationByHandle API with class FileDispositionInfoEx, and setting flags FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS. See the full answer by RbMm.

    0 讨论(0)
提交回复
热议问题