2

I am trying to delete a file in C#, however I am receiving a message that the file is used from another process. What I want to do is to check if the files exists and close it. I am using the following function in order to check if the file is open:

public static bool IsFileInUse(string path)
    {
        if (string.IsNullOrEmpty(path))
            throw new ArgumentException("'path' cannot be null or empty.", "path");

        try
        {
            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { }
        }
        catch (IOException)
        {
            return true;
        }

        return false;
}

and I am trying when the file is in use to close it:

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (File.Exists(file))
{
       File.Delete(file );
}

I got issues in File.Create line, I am receiving the message:

File is being used by another process.

EDIT: I am trying to use lock approach in order to delete the file. Am I suppose to delete the file inside a lock statement? How Can I use properly the lock statement?

Darshak
  • 859
  • 7
  • 18
Jose Ramon
  • 5,572
  • 25
  • 76
  • 152
  • You can not close file that is opened by some other process by any straight forward method. – Adil Jan 28 '16 at 09:38
  • Therefore I should kill the process in order to close the file, right? – Jose Ramon Jan 28 '16 at 09:41
  • 1
    Is that your application? If yes then you can send message to release it or use inter-process lock – Adil Jan 28 '16 at 09:43
  • What is the other process that uses it? Is it your app itself? –  Jan 28 '16 at 09:43
  • You do not handle the return value of IsFileInUse, before calling File.Create. – Jehof Jan 28 '16 at 09:43
  • ... well why don't you just try to delete it and wrap this into a `try ... catch`? I don't think your `IsFileInUse` will work anyway (you can use a file without blocking read access) – Random Dev Jan 28 '16 at 09:47
  • The other process is a thread that uses the file. – Jose Ramon Jan 28 '16 at 09:50
  • You need to use lock between threads to ensure the file handle is released by thread before other takes it for delete. – Adil Jan 28 '16 at 09:51
  • Can you please give me some detail on the lock procedure? – Jose Ramon Jan 28 '16 at 09:54
  • 1
    You can find a lot of article on locking, multi-threading, this is what msdn tell about lock, https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx – Adil Jan 28 '16 at 09:59
  • I am not sure that I catch the lock procedure. I have to abort thread inside a lock statement? – Jose Ramon Jan 28 '16 at 10:27
  • thread.Abort does not really close the thread, right? – Jose Ramon Jan 28 '16 at 10:34
  • I have got to add delete inside a lock statement, right? – Jose Ramon Jan 28 '16 at 10:54
  • @JoseRamon it has nothing to do with thread synchronization. See also [IOException: The process cannot access the file 'file path' because it is being used by another process](http://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being). – Adriano Repetti Jan 28 '16 at 13:21

3 Answers3

9

Why do you suppose that a reading operation will fail if file is in use while a writing operation will not? File.Create() will fail exactly as new FileStream() failed before...

See also IOException: The process cannot access the file 'file path' because it is being used by another process.

Note that your check will fail if the other process didn't open that file exclusively (check FileShare enumeration): file may be open for shared reading, writing and sometimes even for deleting (for example you may be able to read concurrently but not writing however the other process may let you delete that file...).

To close an open file can be really disruptive for the other process, it may crash, nicely handle the problem or...anything else (silently ignore that error and produce random output, open file again and so on...) Is it possible to do it in C#? Yes with some P/Invoke...

1) Let's find the handle for the file you want to unlock. Use NtQuerySystemInformation() and enumerate all handles until you find the one that refers to that file.

2) Duplicate that handle to be valid in your own process using DuplicateHandle().

3) Close just create handle specifying DUPLICATE_CLOSE_SOURCE, it will close both your handle and the original one (of course if your process has enough permissions).

4) Check if file is really closed calling NtQuerySystemInformation() again, if not then you may need to directly close its parent process.

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
2

You have no need to check if the file exists, just try do delete it:

https://msdn.microsoft.com/en-us/library/system.io.file.delete(v=vs.110).aspx

If the file to be deleted does not exist, no exception is thrown.

Try and check the exception

  try {
    File.Delete(file);
  }
  catch (IOException) {
    // File in use and can't be deleted; no permission etc.
  }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 2
    My file is being used by another process, so I need to close that process (thread) in order to delete the file. – Jose Ramon Jan 28 '16 at 10:33
2

In your code, you don't do anything with the IsFileInUse result.

This File.Create(file ).Close(); will also not close a file that is opened by another process. You need to close the process that has the file open, and if it is your own app, close the file handle before trying to delete the file.

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (!checking) 
{
     if (File.Exists(file))
     {
            File.Delete(file );
     }
}
jvanrhyn
  • 2,804
  • 19
  • 14
  • My file is being used by another process, so I need to close that process (thread) in order to delete the file. – Jose Ramon Jan 28 '16 at 10:33
  • @JoseRamon you can do it (close that process, [after you found it](http://stackoverflow.com/a/35058113/1207195)) but it's something to do carefully. – Adriano Repetti Jan 28 '16 at 13:20
  • Is this the way to close a thread https://msdn.microsoft.com/en-US/library/7a2f3ay4(v=vs.80).aspx ? – Jose Ramon Jan 29 '16 at 09:45