Windows Auto Service Update through AWS for the Poor

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



  • The service is updated automatically without user intervention.
  • To store service packs, a free service or service with a long period of free use is used.
  • The solution is simple and does not change the logic of the service.

Choosing a service for storing 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 little restrictions;
  • AWS provides an API for working with cloud storage, for which a library accessible through NuGet (AWSSDK.S3) has been developed.

Mechanism selection


The following libraries for auto-update were considered:
  • AutoUpdate.Net;
  • Squirrel.Windows;
  • ClickOnce.

But all of them did not satisfy our needs.
AutoUpdate.Net required user participation during the upgrade. 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 could not be installed at the system level on Win7 x64.
ClickOnce cannot install the application at the system level. Since we needed to install the service, we also had to refuse this solution.

Update mechanism




  1. During software installation, the installer registers the scheduled launch of the auto-update program in the Windows Scheduler.
  2. Run the auto-update program by the scheduler.
  3. Check for a new installation package on AWS
  4. Getting a new installation package.
  5. Service stop.
  6. Launching a new package in silent mode and completing the update program process.

The new installation package performs the following actions.
  1. Removing a previous version of software from the system (uninstall).
  2. Installing a new software version (install). Along with the new version of the software, the updater is also updated.
  3. Starting the updated service.

The MSI installation package is created using WIX (or another utility) and is straightforward. However, the simplicity of the update process also has disadvantages:
  • there is no error control when installing a new service pack;
  • service pack files are accumulated in the Windows temporary directory.

These shortcomings are not significant. Under normal operation, the installation always occurs without errors. If the update did not happen, 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.

Download packages from AWS


Installation packages will be stored on AWS in this form.

string BucketKeyName = "general/{0}/Setup.msi"; // где {0} – версия установочного пакета

To obtain 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 registration 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();
            }
        }

The following function is used to download the installation package.

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);
// 1. получение текущей версии службы
            var serviceFileInfo = FileVersionInfo.GetVersionInfo(serviceFullFileName);
            var currentVersion = new Version(String.Format("{0}.{1}.{2}", serviceFileInfo.ProductMajorPart, serviceFileInfo.ProductMinorPart, serviceFileInfo.ProductBuildPart) ?? "0.0.0");
            Console.WriteLine(currentVersion);
// 2. получение версии службы с AWS
            var latestVersion = GetLatestVersion();
            Console.WriteLine(latestVersion);
            if (latestVersion<=currentVersion) return;
// 3. загрузка пакета обновления с AWS
            var fileInfo = DownloadInstallerFor(latestVersion);
            if (fileInfo.Exists)
            {
// 4. остановка службы, запуск пакета установки и перезапуск службы
                StopService();
                var process = new Process();
                process.StartInfo.FileName = fileInfo.FullName;
                process.StartInfo.Arguments = "/quiet";
                process.Start();
            }
        }

The presented auto-update mechanism is probably not the only one, but it has worked well for several months of excellent operation. At the same time, the costs of its creation were minimal. More projects: How to create software for the SDK microtomograph in 5233 man-hours to implement support for e-books in the FB2 format Managing access to electronic documents. From DefView to Vivaldi We integrate two video surveillance systems: Axxon Next and SureView. More about the development of software for X-ray tomograph “Sphere”: how to monitor billions of kilowatt hours. Developing a simple plug-in for JIRA to work with the database. To help DevOps: firmware builder for network devices on Debian in 1008 hours












Windows Auto Service Update through AWS for the Poor

Also popular now: