views:

54

answers:

2

My application checks on startup if there is a newer version of a file on a shared network drive. If the one on the network share is newer it copies it to the local application directory and overwrites the old one. My current code to do this goes something like this:

FileInfo sourceFile = new FileInfo(source + "\\" + fileName);
if(sourceFile.Exists) {
    FileInfo destFile = new FileInfo(destination + "\\" + fileName);
    if (destFile.Exists && destFile.LastWriteTime >= sourceFile.LastWriteTime)
    {
        //Using log4net
        log.Info("Current " + fileName + " is newer than the one on the server.");
        return false;
    }
}

Checking the logs, it seems that sometimes the LastWriteTime of the source file is not being detected as newer (event when it is). Am I possibly getting write times and modified times confused? Does anybody have an idea of how to achieve this?

EDIT (and copy of my comment below): The files I am copying are mostly DLLs which I have control over. They are assemblies for the application "Growl for Windows"; they define custom displays. The intent of my application is to check the network share to see if there is a newer version available and to copy that locally if required. That way, we can help to ensure that all our clients are using the most up-to-date display.

EDIT 2:

OK, I fooled around with loading the assemblies and I ran into another problem. It seems you cannot load the same file twice, even if they are from different locations, when they're loaded via Assembly.ReflectionOnlyLoadFrom

+1  A: 

The docs for LastWriteTime do note that the value returned may not be accurate. Note the comment about the Refresh method as well - whilst the code above would almost certainly not require this to be called, if you're creating FileInfo objects and holding onto them for any length of time this may be applicable.

Windows is at liberty to delay updating the actual last write time for a file - as to how long this may be delayed for, check into the Windows API calls dealing with file information.

Will A
+1  A: 

According to MSDN:

This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by the operating system.

If possible, I would try one of the following:

  • Embed the date in the file name
  • Store the file version or date in the file contents.

That way you don't have to worry about issues involving the LastWriteTime property.

Andy West
Unfortunately this isn't an option because I am mostly copying DLLs. Perhaps there is some way to load information about the DLL's build time?
Duracell
@Duracell - If it's about DLLs, does it matter whether it's newer, or simply whether it's different than the one you currently have? IOW, would the DLL on the network share (if there is one) not be the file you want to run by definition? I'm assuming something about your process here, obviously - that you're not building the same DLL locally.
arootbeer
Are they assemblies? Do you have control over them? If so, perhaps the AssemblyName.Version property would be of some use to you. Otherwise you could store metadata about the files outside the files themselves (in other files or a containing folder). Do you have any more contextual information we can use to help you?
Andy West
@Andy West, I'ver been looking into that and will probably be the road I take. I have control over these DLLs. They are assemblies for the application "Growl for Windows"; they define custom displays. The intent of my application is to check the network share to see if there is a newer version available and to copy that locally if required. That way, we can help to ensure that all our clients are using the most up-to-date display.
Duracell