Reputation: 23187
I have an application that runs on my computer and the computers of my colleagues at work. I sometimes push out updates for this application and want the application to detect this automatically (perhaps via database) and shut down and re-open to install the new updates.
I know how I can close an application, but don't know how I can re-open it because when it's not running, I don't know how to execute any code...
Upvotes: 2
Views: 2041
Reputation: 19956
I had a similar problem, but mine was related to unmanageable memory leak that I couldn't find on an app that has to run 24/7. With the customer I agreed that safe time to restart the app was 03:00AM if the memory consumption was over the defined value.
I tried Application.Restart
, but since it seems to use some mechanism that starts new instance while it is already running, I went for another scheme. I used the trick that file system handles persist until process that created them dies. So, from The Application, i dropped the file to the disk, and didn't Dispose()
the handle. I used the file to send 'myself' executable and starting directory also (to add flexibility).
Code:
_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
WorkingDirectory = Application.StartupPath,
Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();
Close()
at the end would initiate app shutdown, and file handle I used for StreamWriter
here would be held open until process really dies. Then...
Restarter.exe comes into action. It TRIES to read the file in exclusive mode, preventing it to gain access until main app wasn't dead, then starts main app, deletes the file and exists. I guess that it can't be simpler:
static void Main(string[] args)
{
string filename = args[0];
DateTime start = DateTime.Now;
bool done = false;
while ((DateTime.Now - start).TotalSeconds < 30 && !done)
{
try
{
StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
string[] runData = new string[2];
runData[0] = sr.ReadLine();
runData[1] = sr.ReadLine();
Thread.Sleep(1000);
Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
sr.Dispose();
File.Delete(filename);
done = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(1000);
}
}
Upvotes: 0
Reputation: 13750
ClickOnce handles updating an application very well. I don't see a problem here, if the user finds that the application is not working (because you have made a change server-side, that warrants them to update the client), they will restart the application and be prompted by the ClickOnce update mechanism to say an update is available (if this has been set up), once the application starts again.
The only way you could tell whether the application was due for an update, whilst the application in question is still running, is to poll the ClickOnce deployment file on the server and compare the version number against the current deployment. Not advisable.
Edit:
Another way to ensure that your users always have the most up-to-date version, is to not include a persistent deployment file and make the user always run from the launch page on your website. This would only dish out the latest and greatest version.
Upvotes: 3
Reputation: 14391
If you are using ClickOnce (and your tag suggests you are?) then you can configure it so your application checks for updates on start-up.
Upvotes: 0
Reputation: 45771
The process you really need to have is something like this:
The "Update application" may need administrative privileges to run if you're updating files on a Vista/Windows7 machine due to UAC, so you'd probably want to embed a manifest to help solve that.
To start another process, the code you'll want to execute is System.Diagnostics.Process.Start()
, for example:
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\cmd.exe";
p.Start();
Upvotes: 1
Reputation: 14783
How about creating a small update app. When your application detects an update it launches the update app and closes itself. The update app downloads and installs the update and then relaunches the main app and closes itself.
Alternatively if the application can update itself when it opens, why does it need to shutdown? Can't it just release any resources it's using etc and perform the update.
Upvotes: 1