Show HN: Vicius – FOSS Windows Software Updater
GitHub - nefarius/vicius: Nefarius' nŏvīcĭus universal software updater agent for Windows.
Nefarius™ vīcĭus updater agent





Nefarius' nŏvīcĭus universal software updater agent for Windows.
About
vīcĭus is a self-contained C++20 executable acting as a software update agent for Microsoft Windows. It can be deployed alongside your product and will take care of periodically checking for newer versions online and notifying the user of pending updates. Its goal is to require the least amount of configuration to get it up and running while providing enough flexibility to be customized for various environments, if desired. It doesn't require any prerequisites being present on the target system and should be able to run on any recent Windows version.
Motivation
Dealing with software update mechanics has been a steady companion for almost 10 years by now, so it's about time to learn from all the mistakes, hardships and shortcomings the various products used have put me through all this time 😅 If you want something done right, you gotta do it yourself 💪
Features

No backend application server required
All you need on the server-side to get going is a web host supporting delivering static JSON files and you're done. GitHub Pages would be a sufficient free hosting solution where you can upload to and deliver the updater configuration from. Take a look at the example server implementation if you wish to write your own backend service.
Self-contained
No need to worry if .NET or other runtimes are present on the target machines, everything it needs is delivered in a single Win32 executable.
(Almost) zero configuration
The bare minimum configuration can be provided by simply compiling in the server URL by adjusting the CustomizeMe.h header file. This does not mean you need to maintain one build for every product you wanna support; you will get multi-tenancy out of the box by simply naming the resulting executable after the following scheme: manufacturer_product_Updater.exe, e.g. nefarius_HidHide_Updater.exe will build the server path as https://example.org/api/nefarius/HidHide/updates.json (or however it is defined in CustomizeMe.h) automatically!

All alternative, more sophisticated configuration options are described in the extended documentation.
If you wish to completely avoid touching the cloned sources have a look at the optional includes.


Sane defaults
We hate wasting time writing configuration files as much as the next person; most configuration options are either optional or have sane default fallback values you can depend on.
Self-updater
Sometimes just the updater process needs an update (e.g. security patches), not the entire product it is watching over. It can update itself if the server-provided instance version is higher than the locally running one.
Self-healing
If run in autostart when the user logs on, it can make sure that scheduled tasks and other supportive components are configured and working properly.
Low resource consumption
The updater process is only invoked on demand (at user logon and once per day via Task Scheduler) and doesn't keep running in the background.
Respects your time
Busy fragging in a game? We won't bother you with any popup windows until you're ready.
Powerful template engine included
Sometimes finding the local resource of interest to check the product version can be more challenging than just having a static, boring file path. You can use inja templates to build your own path resolving logic, all while never having to leave your JSON strings!
Expressive modern changelog support
Update summaries a.k.a. changelogs don't have to be boring slabs of text; Markdown is fully supported! The included fonts are also capable of rendering Fork Awesome icons and system-provided emojis! 🎉 🥳 🍕

Prerequisites

Windows 7 or later (x86, x86_64, ARM64)

Note: currently anything below Windows 10 is untested and low priority


An NTFS formatted volume
An Internet connection
Your software updates need to be packaged in one of the following ways:

Some sort of setup engine like WiX/WixSharp, Inno Setup, Advanced Installer, NSIS or similar
A self-extracting archive (7zip SFX, WinRAR SFX and alike)
A ZIP archive containing portable software (see this guide for details)



Documentation
Head over to the extended documentation for examples and detailed explanations.
Downloads
You can get unsigned build snapshots here. Consider these Nightly-releases.
Signed stable releases will be provided on the repository releases page. Keep in mind though that those releases are built to use my own update infrastructure so in 99% of the cases you probably don't want to use them, at least not without a configuration file!
Screenshots





How to build
Set up Visual Studio 2022 or newer with the C++ Desktop Development workload.
To get binary compression to work upx has to be installed. You can do so via e.g.:

Multi-tenant build example
You do not have to touch the checked out sources if you wish to customize your build.
Assuming a manufacturer name Valkirie and product name HandheldCompanion, create the following folder structure and file .\include\Valkirie\HandheldCompanion\ViciusPostCustomizeMe.h and override the server url in there like so:
#undef NV_API_URL_TEMPLATE
#define NV_API_URL_TEMPLATE     "https://raw.githubusercontent.com/Valkirie/HandheldCompanion/main/Valkirie_HandheldCompanion_Updates.json"
Now you can build from the command line pointing the compiler to the directory of your header(s) like so:
msbuild .\src\vīcĭus.vcxproj /p:Configuration=Release /p:CustomIncludes="${PWD}\include\Valkirie\HandheldCompanion\" /p:UpdaterName=Valkirie_HandheldCompanion_Updater
This will produce the binary Valkirie_HandheldCompanion_Updater.exe with the server URL of your custom header file baked into it!
You're of course free to put the custom header files anywhere on your system (like your own private repository), they do not need to be put under the project root directory.
TODOs
For more details check the issue tracker.
Non-exhaustive list of things open or in-progress...
Must-haves

 Add silent update option

 Docs
 Types
 Implementation (see #15)


 Add message box dialog if the user launches the updater with no args

 Standard text if we are up to date
 Inform if Betas are available



Nice-to-haves

 Localization
 Add Authenticode signature checks (see #7)

 Crypto primitives
 Model types
 Business logic


 Design Beta-Release support

 WizardPage::MultipleVersionsOverview


 Make app icon customizable
 Add "Light" theme
 Support closing and restarting applications before and after the main update
 Support running prerequisites installation before main update
 Support running the update as Administrator
 Implement machine-wide registration
Currently only the user executing the updater will run registrations, which is sufficient for most cases
 Postpone update dialog popping up if the product is currently in use
 Allow using a HTTP proxy address via configuration
 Add SAL annotations

Done
Expand me!

 Make UI DPI-aware
 Finalize UI design

 WizardPage::Start
 WizardPage::SingleVersionSummary
 WizardPage::DownloadAndInstall


 Finalize local updater config JSON format
 Add retry-logic (e.g. retry failed downloads etc.)
 Add some fallback code if the temp directory isn't available
 Handle all known error-cases

 Server response errors
 Release download errors
 Setup launch errors


 Documentation

 About page
 JSON Schemas
 Specify supported Command Line Arguments
 Exit Codes
 Emergency Feature
 Server Discovery
 Logging
 Common Errors
 Local Configuration
 Remote Configuration


 Allow setting the download directory
 Implement "postpone" choice behaviour
 Implement Task Scheduler

 Registration
 Removal


 Finalize REST API design
 Add info dialog before self-updating UAC dialog comes up
 Add self-updater logic

 Tests
 Fix issues launching from write-protected directory like Program Files


 Implement Product Version detection

 RegistryValue
 FileVersion
 FileSize
 FileChecksum
 CustomExpression


 Add some logging
 Tidy up and improve includes

 Optimize build times
 Use pre-compiled headers?


 Support environment variables or custom placeholders in path strings and alike


Sources & 3rd party credits
This tool benefits from these awesome projects ❤ (appearance in no special order):
Dependencies

Dear ImGui
Simple and Fast Multimedia Library
ImGui-SFML
Argh! A minimalist argument handler
Markdown renderer for Dear ImGui using MD4C parser
IconFontCppHeaders
Ruda Font
Fork Awesome
REST client for C++

libcurl


cURLpp
JSON for Modern C++
Magic Enum C++
Semantic Versioning library for modern C++
WinReg
Portable C++ Hashing Library
A modern C++ scope guard that is easy to use but hard to misuse
Fast C++ logging library
A Template Engine for Modern C++
Simple C++ ini parser
MimeTypes
A C++ header-only HTTP/HTTPS server and client library
A C library for reading, creating, and modifying zip archives
My opinionated collection of C++ utilities

Literature & references

Using Icon Fonts

imgui_freetype
Using Colorful Glyphs/Emojis


Image Loading and Displaying Examples
DailyTaskScheduler
INFO: Windows Rundll and Rundll32 Interface
How can I run a child process that requires elevation and wait?
Execute from Alternate Streams
Vista Goodies in C++: Showing Friendly Messages with Task Dialogs
How to retrieve files digital signature information?
Windows Authenticode Portable Executable Signature Format
How To Get Information from Authenticode Signed Executables
VERSIONINFO resource
Semantic Versioning 2.0.0
Windows Platform Comparison Environment Variable Reference
C++ Library Manager for Windows, Linux, and MacOS
Silently Install EXE and MSI setup applications (Unattended) - How To Guide
Markdown Guide Basic Syntax

DPI-awareness

Writing Win32 apps like it's 2020: A DPI-aware resizable wizard
imgui-sfml / DPI-awareness on Windows
Examples: A very simple example of High DPI changing handling for Win32
imgui / Blurry fonts in high DPI
thedmd/imgui/tree/feature/hidpi-support

