How to determine if a file is used before deletion?

I am writing a Windows service that may delete a file at some point. Since the service is dealing with a regular IO file, it is possible that the file may be used during deletion.

I am currently trying to remove and respond later when an exception occurs. The code looks something like this:

try { File.Delete(file); Status = ResponseStatus.Ok; } catch (IOException e) { Status = ResponseStatus.FileInUse; } finally { return Status; } 

How to determine if a file is being used without using an exception?

+4
source share
4 answers

It makes no sense to try to determine the front whether the file is being used - what if someone opens the file between your discovery code and the delete code? You still need your existing code to handle this.

The code you already have is exactly what you need to do.

+13
source

As Richie says, catching an exception is probably the best approach here.

But what if you want to delete 10 files and you do not want it to fail halfway? You really need some way to protect the overall transaction. Therefore, it is useful to be able to passively check if a file is being used. You can determine if a file is being used (or read-only, which also makes it invulnerable) by simply trying to open it for writing (and then, if you succeed, close it immediately). This alone does not guarantee that a subsequent uninstall attempt will succeed.

Other approaches that might work would be: - move / rename the file before deleting (put them in a safe place so that you know that they cannot be opened by another process later), so that you can "cancel" the transaction, if any of the individual move operations fail. - catch the exception and queue for a future attempt to delete the file (either in your own program, or you can mark the file to automatically delete Windows at the next reboot)

+3
source

Extending Richie's correct answer

When working with the file system, you can never reliably if the operation is successful. All you can do is try to complete the operation and see if it succeeded.

A file system is a moving target that you do not control. Any number of external and other user events can affect the file system outside of your control. In many ways, this is similar to multi-threaded programming where synchronization is not possible. Whenever you see the code as below, there is a subtle error

 if (File.SomeTypeOfCheck(somePath) { File.DoSomeOperation(somePath); } 
+3
source

If you just want to check if the deletion was successful without exception, you just need to declare P / Invoke for DeleteFile .

 [DLLImport("Kernel32.dll", SetLastError = true)] public static extern bool DeleteFile(string fileName); 

This will return true if the deletion was successful and false if it was not. If you need a specific error code, you can call Marshal.GetLastWin32Error()

+2
source

All Articles