Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Geert van Horrik's 'Updater' in Visual Studio Community Edition With Small Changes

5.00/5 (4 votes)
1 Dec 2014CPOL3 min read 15.7K   245  
I needed an 'Update' solution for a project, and modified Geert van Horrik's 'Updater' to do so. This is the solution in Visual Studio Community Edition

Introduction

As said in the snippet, I needed an Update solution for a project, and came across Geert van Horrik's 'Updater'. He hasn't touched it in some time, and since I had to modify it a bit to get it running in Visual Studio Community Edition, I figured I'd post the solution here for others to begin their own solutions a little more easily than I did.

The Main Changes (that I remember)

First, I made the project link with the static MFC libraries instead of DLLs. As far as I understand, in order to distribute Updater, you need to either distribute the MFC dll, which is about 4 MB if I remember correctly, or go the static library route. With static libraries, the completed executable comes in at about 6 MB.

The other change I performed offset this difference.  It was making the Post-Build step use a newer version of upx.exe. Upx.exe is the 'Ultimate Packer for eXecutables,' per their claim, and using it brought the final executable down to 1605 KB from 5826 KB. (The original upx.exe threw errors because it was so old, and things have changed since those days.)

I also had to modify some code in CCheckVersion::CheckVersionSeparately, because the original code refused to do a straight check of the file version I'd set in updatefile.xml as compared to the settings.ini file file version. There were also slight changes made in CHttpFileObject::OnStartDownload, and possibly some other stuff I've forgotten.

Using the code

You should be able to unzip the file to a subdirectory and open the project in Visual Studio, as long as it isn't the Express Edition. The Community Edition has MFC in it, which is necessary for compilation.

I've placed copies of my updatefile.xml and settings.ini files in the release and debug directories. Both of them will need to be modified appropriately for your situation, and the updatefile.xml will need to be moved to your server. As they are, once the names are changed correctly, they show how to use Geert's code to use an update file rather than simply overwriting stuff in the program directory. In other words, I use Geert's Updater to run an installer, and it took me a little bit of poking around to get it to work.

If you dig into it, you might see that the original setup was looking for you to specify the application path in the settings.ini file, in the [APPLICATION] section. I removed that necessity.

Points of Interest

In order to call Updater from your application, you will need elevated priveledges. To do so, here's my current menu callback code:

C++
void ui::MainMenu::checkForUpdates(dwl::Object * ) {
   SHELLEXECUTEINFO shExInfo = {0};
   shExInfo.cbSize = sizeof(shExInfo);
   shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
   shExInfo.hwnd = 0;
   shExInfo.lpVerb = _T("runas");
   //The following will need to be modified per your framework:
   wString file = gDwlApp->appPath() + _T("\\Updater.exe");
   shExInfo.lpFile = file.c_str();
   shExInfo.lpParameters = _T("");
   shExInfo.lpDirectory = 0;
   shExInfo.nShow = SW_SHOW;
   shExInfo.hInstApp = 0;  

   ShellExecuteEx(&shExInfo);
   }

The Updater is located in the same directory as the application.

Another item to be aware of is that the 'nozip' exe doesn't include the upx.exe file, which you will need to download yourself from SourceForge.

Thanks

Deep thanks goes to Geert van Horrik, for the huge amount of time he must have spent on Updater. And for making it public. Thank you Geert.

PS

If you come up with further improvements, please post them in the comments. For instance, one item I haven't looked into is it seems the title bar often gets screwed up, probably due to theming for some reason. I also haven't looked into silent running of Updater at program startup, in order to automatically notify the user of updates. That aspect will probably require silent elevation of priveledges, which may not already work in the current version. If you figure out a solution to either of these before I get to them, please holler.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)