How to force FileSystemWatcher to wait till the file downloaded?

satyajit picture satyajit · Mar 8, 2011 · Viewed 13.7k times · Source

I am downloading a file and want to execute the install only after the download is complete. How do I accomplish this? Seems like FileSystemWatcher onCreate event would do this but this happens in a different thread, is there a simple way to force the waiting part to happen in the same thread.

Code I have so far

 FileSystemWatcher w = new FileSystemWatcher(@"C:/downloads");
 w.EnableRaisingEvents = true;
 w.Created += new FileSystemEventHandler(FileDownloaded);

 static void FileDownloaded(object source, FileSystemEventArgs e)
 {
    InstallMSI(e.FullPath);
 }

I looked at SynchronizingObject and WaitForChangedResult but didn't get a solid working sample.

Answer

ukhardy picture ukhardy · Mar 8, 2011

Try:

FileInfo fInfo = new FileInfo(e.FullPath); 
while(IsFileLocked(fInfo)){
     Thread.Sleep(500);     
}
InstallMSI(e.FullPath);


static bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;
    try {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException) {
        return true;
    }
    finally {
        if (stream != null)
            stream.Close();
    }   
    return false;
}