posted on Wednesday, January 05, 2005 5:13 PM
by
johnwood
Auto-Updater Class
I’m on a roll now. Here's another useful class. It's an auto-updater component that works on a network (not the web). It detects when files change in a specific folder, prompts you to upgrade and then copies over the files and restarts the process. This is bare minimum code, thoroughly untested, but it does appear to work in basic scenarios. Unlike some other auto-updaters, it works on any executable and doesn’t require any source code changes.
Just put it into a project and set the entry point to the Main function. Then run it as follows:
C:\> MonitorApp c:\run\myapp.exe z:\updates any_arguments_for_myapp
Here’s the code:
public class MonitorApp
{ Process monitorApp = null;
bool restart = false;
FileSystemWatcher watcher = null;
void FileUpdated(object sender, FileSystemEventArgs args)
{ watcher.EnableRaisingEvents = false;
if (MessageBox.Show("Install application update and restart?", "Update Detected", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)==DialogResult.OK)
{ restart = true;
monitorApp.CloseMainWindow();
}
watcher.EnableRaisingEvents = true;
}
void CopyNewFilesAndMonitor(string updateFolder, string targetFolder)
{ foreach (string newFile in Directory.GetFiles(updateFolder))
{ string existingFile = Path.Combine(targetFolder, Path.GetFileName(newFile));
if (File.GetLastWriteTime(existingFile)<File.GetLastWriteTime(newFile))
File.Copy(newFile, existingFile, true);
}
watcher = new FileSystemWatcher(updateFolder);
watcher.Changed += new FileSystemEventHandler(FileUpdated);
watcher.EnableRaisingEvents = true;
}
static void Main(string[] args)
{ string appToRun = args[0];
string updateFolder = args[1];
string appArguments = args.Length>2 ? "" : string.Join(" ", args, 2, args.Length-2); MonitorApp monitor = new MonitorApp();
monitor.CopyNewFilesAndMonitor(updateFolder, Path.GetDirectoryName(appToRun));
monitor.monitorApp = Process.Start(appToRun, appArguments);
monitor.monitorApp.WaitForExit();
if (monitor.restart) // if we have to restart, run this app again.
Process.Start(Process.GetCurrentProcess().MainModule.FileName, string.Join(" ", args)); }
}
There's three main routines:
Main is the entry point into the application. The first thing this does is to run CopyNewFilesAndMonitor. Then it spawns a secondary process and waits for it to exit. If a restart flag is set, it'll then restart the application.
The CopyNewFilesAndMonitor function does just as it says: copies new files from a folder and monitors the source files. If you wanted to adapt this to work with the web, it could instead download files and then set up a timer to poll the website for updates, calling FileUpdated when it found an update.
FileUpdated is called by the FileSystemWatcher whenever anything in the update folder is changed. This simply closes the spawned application and sets a flag to restart the current process.
A copy of the source and binary can be found here.