One day a guy came to
Edison Software . Looking at the bill, he squinted and exclaimed: “Why is it so expensive ?! I'm poor! ” It has become a catch phrase and label for a whole class of projects. So, we needed to implement an automatic update for the Windows service, while meeting the following conditions.

- The service is updated automatically without user intervention.
- A free service or service with a long period of free use is used to store service packs.
- The solution is simple and does not change the logic of the service.
Choosing a service to store packages
Amazon Web Services (AWS) was chosen as the service for storing service packs. The main reasons for his choice were:
- AWS provides a year of free access with few restrictions;
- AWS provides an API for working with cloud storage, for which a library is developed that is accessible through NuGet (AWSSDK.S3).
The choice of mechanism
The following libraries for autoupdate were reviewed:
- AutoUpdate.Net;
- Squirrel.Windows;
- ClickOnce.
But they all did not satisfy our needs.
AutoUpdate.Net required user
interaction when updating. And the library itself has not been supported for a long time.
Squirrel.Windows had all the necessary functions, however, it found a bug due to which the application was not installed at the system level on Win7 x64.
ClickOnce cannot install an application at the system level. Since we needed to install the service, this solution also had to be abandoned.
Update mechanism

')
- During the installation of the software, the installer registers in the Windows scheduler the launch of the auto-update program on a schedule.
- Run the auto-update program scheduler.
- Check for a new installation package on AWS
- Getting a new installation package.
- Stop the service.
- Running the new package in silent mode, and completing the updater process.
The new installation package performs the following actions.
- Uninstall the previous version of the software from the system.
- Install new software version (install). Along with the new software version, the update program is also updated.
- Start the updated service.
The MSI installation package is created using
WIX (or another utility) and is straightforward. However, the simplicity of the update process has disadvantages:
- no error control when installing a new service pack;
- files of service packs accumulate in the Windows temporary directory.
These drawbacks are not significant. In normal operation, the installation always occurs without error. If the update did not occur, the user can always manually reinstall the software. The size of the installation package is small, updates are also not frequent, so the presence of files in the Windows temporary directory does not cause problems.
Downloading AWS Packages
Installation packages will be stored on AWS in this form.
string BucketKeyName = "general/{0}/Setup.msi";
To get the latest version number, which is stored on the AWS service, the following function is implemented (AwsKeyId, AwsSecretKey and AwsRegion are available in your account after registering on the service).
private static Version GetLatestVersion() { using (var client = new AmazonS3Client(AwsKeyId, AwsSecretKey, AwsRegion)) { var listRequest = new ListObjectsRequest() { BucketName = BucketName, Prefix = "global/", Delimiter = "/", }; var response = client.ListObjects(listRequest); var versions = response.CommonPrefixes.Select(prefix => { try { var versionString = prefix.Replace(listRequest.Prefix, "").Replace("/", ""); return new Version(versionString); } catch { return new Version(); } }); return versions.Max(); } }
To download the installation package, use the following function.
private static FileInfo DownloadInstallerFor(Version version) { var request = new GetObjectRequest { BucketName = BucketName, Key = string.Format("general/{0}/Setup.msi", version.ToString()), }; string dest = Path.Combine(Path.GetTempPath(), request.Key); using (var client = new AmazonS3Client(AwsKeyId, AwsSecretKey, AwsRegion)) { using (var response = client.GetObject(request)) { if (!File.Exists(dest)) { response.WriteResponseStreamToFile(dest); } } } return new FileInfo(dest); }
The main function of the auto-update program.
static void Main(string[] args) { var currentFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); var serviceFullFileName = Path.Combine(currentFolder, ServiceFileName); Console.WriteLine(serviceFullFileName);
The presented auto-update mechanism is probably not the only one, but it has worked well for several months of excellent work. In this case, the cost of its creation were minimal.

More projects:
How to create software for a microtomograph for 5233 man-hoursSDK for the introduction of support for e-books in FB2 formatControl access to electronic documents. From DefView to VivaldiIntegrating two video surveillance systems: Axxon Next and SureViewRead more about the development of x-ray tomograph softwareSphere: how to monitor billions of kilowatt-hoursDeveloping a simple plugin for JIRA to work with a databaseTo help DevOps: a firmware builder for network devices on Debian for 1008 hoursWindows Service Auto Update for Poor AWS