سؤال

I need to do a quick and dirty way of upgrading my application.

Currently I have an exe per every release.

If exe is wrong i flash a message "relase X found on db, you are using exe for release Y, please download the correct vetsion".

I have every exe at a fixed addresss, like: http://myip.com/exes/N/Project.exe (where N is the releease)

So my idea was instead of the message above i would prompt the user "the correct exe will be downloaded, press ok to continue".

my idea is after OK:

1) Run with ShellExecute another exe (let's call id Update.exe) that takes care of downlaod and replace (this exe could be stored in exe resources)

2) Close the application

2) Update.exe will download the correct exe from internet and save it to a temp folder

4) Update.exe will delete Project.exe and replace it with the downloaded one

5) Update.exe will run the new Project.exe

So the corret exe will be run and the user will have the new exe in the same location as the old exe. This would be a non hortodox upgrade (not using Windos update, but believe me I need this. I don't ue WIndows update).

Could you comment on this approach? Or suggest a similar trick?

هل كانت مفيدة؟

المحلول

I do this, and it works well for me:

After OK, this is done in UpdateOKClick:

  1. Display a progress bar and use InternetReadFile to read the new version install executable and write it to a temporary file (use GetTempPath in the System unit).
  2. Display a message box stating "Download complete. Closing program to install new version."
  3. Call ShellExecute to run the new version install executable from the temporary file location. The trick is that I call the install program (I'm using Inno Setup) with two special parameters: /silent and /noicons.
  4. Run Application.Terminate to close the program.

The program terminates immediately, and the install has a bit of a delay to it, so it starts after the program is already closed. The user will see the install progress screen that Inno Setup displays, but because of the two parameters, it will not ask any questions.

The final step of the Inno Setup install is to launch the program. It does so calling it with a /webupdate parameter.

When the program is launched, it checks if the webupdate parameter was used. If so, it does any initialization necessary for the new version, and then displays a message box stating "Program is now updated to Version xxx".

There are a lot of checks and possible messages to issue along the way, including giving the user the option to cancel at any time, but that is basically it.

... and I don't have to delete the previous executable. It just gets overwritten. That will fail if the user has a second instance of the program open, but that's another thing to check for.

نصائح أخرى

I would take a slightly different approach. Instead of using a separate exe for the downloading, I would have the main exe do it in a background thread instead, or use the Windows BITS service (which accepts HTTP urls). This way, the app can stay running while the download is in progress, and can be restarted at the user's leisure. Whenever the main exe is started, it could check for the presence of a completed update file in the temp folder, and if found then extract a loader exe, run it, and exit. The loader then waits for the main exe to finish exiting, moves/renames the update file, and runs it.

Here is the approach I use for our local in-house apps. It relies on the fact that you can rename an *.exe file while the application is running.

An updater class downloads an XML file which contains update information. It compares that info with the currently running application. If an update is needed, it downloads the updated files (basically a file copy since they're located on a local server) and adds a .update extension. Then it renames the currently running exe by adding .bak extension. Then rename the downloaded file to the original exe name, and restart the application.

That's just a quick overview. There are checks that account for error or problems, as well as prompts for the user. There is also cleanup code to delete older backups etc, or to rollback to a previous version if necessary. In some cases, you can force the update by doing the above at startup without user interaction.

While maybe not the best approach, it works very well on our local LAN.

Yet another approach, since you are going to rewrite your file structure anyway: Have a small stub program do the version check, prompt for (and do) the update, then start the actual app.

What I have always done, if updating only concerns main-exe :

  • Download new exe to temp location
  • Call (ShellExecute) new exe with parameters, like main.exe -update -c:\oldlocation\
  • Close

My exe-file (in this case, the new one) will start in a special "update" mode, where it waits for the exe it is supposed to replace to exit, then copies itself and overwrites it, runs the new exe and exits.

To get rid of downloaded updates, the new exe could be called with some params like -doneupdating -c:\tempdownloadlocation, which the exe could then delete.

This approach is pretty simple to maintain, since everything is contained in the main exe, and it is easily expandable to handle extra files

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top