1

Using Windows API, is it possible to rename a file that's open in another process without FILE_SHARE_DELETE permissions?

I thought it's impossible based on CreateFile docs that say:

Note: Delete access allows both delete and rename operations.

Consistent with that, renaming through regular rename in the end-user command prompt, I often encountered The process cannot access the file because it is being used by another process.; a similar error happens with renaming through end-user GUI and through python's os.rename.

However, this highly-upvoted answer seems to state the opposite:

Deleting will fail if any other process has the file opened without delete sharing, renaming is never a problem.

And it's not just a minor point; the entire answer depends on that statement: it only solves the OP problem if renaming wouldn't fail when delete would.

What am I missing?

Note: If it matters, I am referring to Windows 10, using C++ API (which I assume is strictly more powerful than C# API).

Edit: moved the code snippet to a new question.

Community
  • 1
  • 1
max
  • 49,282
  • 56
  • 208
  • 355

1 Answers1

2

It is only possible as a deferred operation, using the MOVEFILE_DELAY_UNTIL_REBOOT flag. It is a priviledged operation that requires the user context to enable the Administrator token (UAC). This is how installers replace a file while in use, and then they ask for the operator to reboot the system.

As you can see, is not trivial and you should try to avoid doing this.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • But then why does `File.Replace` with 3 arguments succeed even if the destination file is in use? If renaming destination to the backup name is delayed until reboot, then renaming of source to destination would fail, wouldn't it? – max Apr 23 '17 at 18:00
  • `File.Replace` is a different operation. It maps to [`ReplaceFile`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365512(v=vs.85).aspx). See http://stackoverflow.com/questions/32860388/replacefile-alternative-when-application-keeps-file-locked for why this can succeed when `lpReplacedFileName` is opened by another app. – Remus Rusanu Apr 23 '17 at 18:14
  • Wow the entire answer to my question is embedded in a [deleted answer](http://stackoverflow.com/a/32862684/336527) to a very different question... So IIUC `ReplaceFile` just changes the file metadata (=directory entry) which isn't protected by permissions. Very neat, I'm surprised it's not a well-known thing because it's the only way to implement atomic file writes on Windows. Maybe you could add this information to your answer (assuming it's correct)? – max Apr 23 '17 at 18:28
  • 1
    Hmm, when I called `ReplaceFile` with 3 arguments when either source or destination file had open handles without `FILE_SHARE_DELETE`, I got `ERROR_SHARING_VIOLATION`. Is there anything else I need to do to make this function work as described? – max Apr 23 '17 at 20:35