Question

I have a program with a FileSystemWatcher which watches for itself to be updated to a new version by an external program (which involves renaming the current executable and copying a new one in its place).

The problem is, when the file it's watching is in the Program Files directory, the FileVersionInfo.GetVersionInfo() doesn't get the new version information, it returns the same thing it got the first time. So if it updated from 1.1 to 1.2, it would say "Upgraded from 1.1 to 1.1" instead of "Upgraded from 1.1 to 1.2". It works correctly in the debug directory, but under Program Files, it won't get the correct value.

Here's the essence of what it's doing, without all the exception handling and disposing and logging and thread invoking and such:

string oldVersion;
long oldSize;
DateTime oldLastModified;
FileSystemWatcher fs;
string fullpath;

public void Watch()
{
    fullpath = Assembly.GetEntryAssembly().Location;
    oldVersion = FileVersionInfo.GetVersionInfo(fullpath).ProductVersion;
    var fi = new FileInfo(fullpath);
    oldSize = fi.Length;
    oldLastModified = fi.LastWriteTime;

    fs = new FileSystemWatcher(
        Path.GetDirectoryName(fullpath), Path.GetFileName(file));
    fs.Changed += FileSystemEventHandler;
    fs.Created += FileSystemEventHandler;
    fs.EnableRaisingEvents = true;
}

void FileSystemEventHandler(object sender, FileSystemEventArgs e)
{
    if (string.Equals(e.FullPath, fullpath, StringComparison.OrdinalIgnoreCase))
    {
        var fi = new FileInfo(fullpath);
        if (fi.Length != oldSize
            || fi.LastWriteTime != oldLastModified)
        {
            var newversion = FileVersionInfo.GetVersionInfo(fullpath).ProductVersion;
            NotifyUser(oldVersion, newversion);
        }
    }
}

How do I make GetVersionInfo() refresh to see the new version? Is there something else I should be calling instead?

Was it helpful?

Solution

I'm answering my own question because there doesn't seem to be much interest. If anyone has a better answer, I'll accept that instead...

As far as I can tell, there is no way to make it refresh. Instead I worked around the issue:

return AssemblyName.GetAssemblyName(fullpath).Version.ToString();

Combined with code that makes sure it only gets called once, it seems to work just fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top