This article will teach you how to use the AutomaticUpdater in apps without a UI such as Windows Services and console apps. If you're making an app with a graphical user interface, then see one of the following articles:
If you're making a GUI app that happens to have Windows Services that you'd like to update, then you can just use the GUI version of the AutomaticUpdater and Start and Stop Windows Services as part of your update.
You need wyBuild to use the AutomaticUpdater, so download wyBuild now. You can use it free for 21-days with no restrictions. And if you don't like it you can uninstall it - no hard feelings & no files laying around.
Then, work yourself through steps 1-3 of the step-by-step walkthrough. This will teach you how to make update patches. Once you've read the walkthrough you're ready to add the AutomaticUpdater to your app:
The first thing you need to do is add the AutomaticUpdater.dll reference to your app. You can do this by right clicking the "References" folder in Visual Studio, clicking "Add Reference...", then choosing the "Browse" tab in the "Add references" dialog:
Then simply choose the correct AutomaticUpdater.dll for your app. There are 2 separate builds of the AutomaticUpdater: one for .NET 2.0, 3.0, and 3.5 apps and one for .NET 4.x apps.
If your app is compiled for .NET 2.0, 3.0, or 3.5 then use AutomaticUpdater.dll located in the "AutomaticUpdater" folder:
C:\Program Files\wyBuild\AutomaticUpdater\AutomaticUpdater.dll or C:\Program Files (x86)\wyBuild\AutomaticUpdater\AutomaticUpdater.dll
If your app is compiled for .NET 4.x then use AutomaticUpdater.dll located in the "AutomaticUpdater\Microsoft .NET 4.0" folder:
C:\Program Files\wyBuild\AutomaticUpdater\Microsoft .NET 4.0\AutomaticUpdater.dll or C:\Program Files (x86)\wyBuild\AutomaticUpdater\Microsoft .NET 4.0\AutomaticUpdater.dll
The AutomaticUpdaterBackend
class contains all the functionality to add automatic updating to your service or console app. The way to use the AutomaticUpdaterBackend
differs between Windows Services and Console Apps, so we've split it into 2 separate examples:
If you're using the AutomaticUpdater with a Windows Service, the first thing you need to do is make sure your service will be installed as a "LocalSystem" service. Please note that a "LocalSystem" service is different than a "LocalService" service:
Create and instance of the AutomaticUpdaterBackend
class in the OnStart()
method of your service:
using wyDay.Controls; static AutomaticUpdaterBackend auBackend; protected override void OnStart(string[] args) { auBackend = new AutomaticUpdaterBackend { //TODO: set a unique string. // For instance, "appname-companyname" GUID = "a-string-that-uniquely-IDs-your-service", // With UpdateType set to Automatic, you're still in // charge of checking for updates, but the // AutomaticUpdaterBackend continues with the // downloading and extracting automatically. UpdateType = UpdateType.Automatic, // We set the service name that will be used by wyUpdate // to restart this service on update success or failure. ServiceName = this.ServiceName }; auBackend.ReadyToBeInstalled += auBackend_ReadyToBeInstalled; auBackend.UpdateSuccessful += auBackend_UpdateSuccessful; //TODO: use the failed events for logging & error reporting: // CheckingFailed, DownloadingFailed, ExtractingFailed, UpdateFailed // Initialize() and AppLoaded() must be called after events have been set. // Note: If there's a pending update to be installed, wyUpdate will be // started, then it will talk back and say "ready to install, // you can close now" at which point your app will be closed. auBackend.Initialize(); auBackend.AppLoaded(); if (!auBackend.ClosingForInstall) { // sees if you checked in the last 10 days, if not it rechecks CheckEvery10Days(); //Note: Also, since this will be a service you should call // CheckEvery10Days() from an another thread (rather // than just at startup) //TODO: do your normal service work } }
You'll notice we made a call to a function CheckEvery10Days()
. This function checks whether we checked in the last 10 days, and if not, begins checking for updates:
static void CheckEvery10Days() { // Only ForceCheckForUpdate() every N days! // You don't want to recheck for updates on every app start. if ((DateTime.Now - auBackend.LastCheckDate).TotalDays > 10 && auBackend.UpdateStepOn == UpdateStepOn.Nothing) { auBackend.ForceCheckForUpdate(); } }
Since we set the UpdateType
to UpdateType.Automatic
, when you check for updates they will automatically be downloaded and extracted. Once they are ready to be installed the ReadyToBeInstalled
event will be called. From there you can stop all running processes and threads in the service and finish the installation of the update:
static void auBackend_ReadyToBeInstalled(object sender, EventArgs e) { // ReadyToBeInstalled event is called when // either the UpdateStepOn == UpdateDownloaded or UpdateReadyToInstall if (auBackend.UpdateStepOn == UpdateStepOn.UpdateReadyToInstall) { //TODO: Delay the installation of the update until // it's appropriate for your app. //TODO: Do any "spin-down" operations. auBackend.InstallNow() will // exit this process using Environment.Exit(0), so run // cleanup functions now (close threads, close running programs, // release locked files, etc.) // here we'll just close immediately to install the new version auBackend.InstallNow(); } }
After the update has completed your service will be restarted.
If you're using the AutomaticUpdaterBackend in your service then you must ensure your service name is correct (and the same) in all your code. This means confirming your service name in at least 3 places (sometimes more):
If your service name is different in your service installer, and your various service code files, then this will cause problems in the updating. One such problem is your service will not re-start after a successful update or an error. There are other problems as well. This is why you must ensure you service name is correct in all places it's used.
Using the AutomaticUpdaterBackend
class in console apps is similar to how you use it in a Windows Service. The only differences are that you create the AutomaticUpdaterBackend
instance in the Main()
function of your app and you don't use the ServiceName
property. For example:
auBackend = new AutomaticUpdaterBackend { //TODO: set a unique string. // For instance, "appname-companyname" GUID = "a-string-that-uniquely-IDs-your-app", // With UpdateType set to Automatic, you're still in // charge of checking for updates, but the // AutomaticUpdaterBackend continues with the // downloading and extracting automatically. UpdateType = UpdateType.Automatic };
We talked about just one event, ReadyToBeInstalled
, but there are many more. For instance, you should handle errors using the CheckingFailed
, DownloadingFailed
, ExtractingFailed
, UpdateFailed
.