1

I have a problem that is driving me mad. Maybe you could help ;)

I'm tracking file changes on the folder with FileSystemWatcher and copy changed files to another folder. I don’t want to copy the file until it is done being saved. I cannot find a solution that works at the same time for all 3 scenarios below:

1) New file being copied into the folder 2) Existing file being overwritten by copying new one 3) File is opened by another process (i.e. Word) I have tried IsFileLocked method from the thread below. c# check if file is open

It will work for copying but the problem is that function will always return TRUE for opened OFFICE files (maybe for some others as well).

I also tried to check in the loop if the file size changes but it’s seems to be impossible as FileInfo.Length always return the target size (even though file is still being copied).

I'm using that function to check if file is in use

public static bool IsFileLocked(string path)
{
    FileInfo fileInfo = new FileInfo(path);
    FileStream stream = null;

    try
    {
        stream = fileInfo.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (UnauthorizedAccessException)
    {
        // file created with readonly flag
        return false;
    }
    catch (FileNotFoundException)
    {
        return false;
    }
    catch (IOException ex)
    {
        int errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
        bool islocked = errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
        return islocked;
    }
    finally
    {
        if (stream != null)
        {
            stream.Close();
            stream.Dispose();
        }
    }
    //file is not locked
    return false;
}

Do you know how to distinguish if it's opened by some application or being copied?

Community
  • 1
  • 1
macfly
  • 255
  • 3
  • 13
  • Are you opening the file for exclusive read? – Rowland Shaw Jun 03 '15 at 07:55
  • please take a look at my updated question – macfly Jun 03 '15 at 13:03
  • You probably want to change your logic to copy the file whilst you've got the file locked for exclusive read - otherwise another process could modify it between you checking if it's locked, and completing your processing. – Rowland Shaw Jun 03 '15 at 13:44
  • Rowland could you explain what you mean? The problem is that I have to track if user is done coping file via Windows Explorer, Total Commander etc. or if he or she is done saving it via for example Office on folder1 before I copy that file to another folder2. I want to be sure that I copy full file and not only the part of it. – macfly Jun 04 '15 at 14:39
  • Currently you have a method to see if it's in use. It actually gets a read stream if it is not in use elsewhere, but you don't use that, instead you again try to do "something" with the file after your check completes; at which point "something else" may have jumped in and started to read the file. Instead you could actually use the stream to do your processing whilst you know the file is in a good state to read from. – Rowland Shaw Jun 04 '15 at 16:36
  • But it won't solve my problem. For file opened with MS Office it will always throw exception – macfly Jun 07 '15 at 12:24
  • It shouldn't if those files are not open in Office (read: it doesn't for me) – Rowland Shaw Jun 08 '15 at 08:15

0 Answers0