Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

Self Patching App Tutorial

Süleyman Yasir KULA edited this page Mar 8, 2020 · 13 revisions

In this tutorial, you will see how to add self patching support to a simple console app. This process can easily be applied to a GUI-based app, as well.

Video tutorial: https://www.youtube.com/watch?v=YUwgsfYQKFo (legacy tutorial)

  • create a console app project and add SimplePatchTool.dll as reference to it
  • change Program.cs as follows:
using SimplePatchToolCore;
using System;
using System.IO;
using System.Threading;

namespace SPTSelfPatchingAppDemo
{
	class Program
	{
		private const int VERSION = 1;
		private const string VERSION_INFO_URL = "SEE: https://github.com/yasirkula/SimplePatchTool/wiki/Generating-versionInfoURL";
		private const string SELF_PATCHER_EXECUTABLE = "SelfPatcher.exe";

		static void Main( string[] args )
		{
			Console.WriteLine( "VERSION: " + VERSION );
			Console.WriteLine( "Checking for updates..." );

			SimplePatchTool patcher = new SimplePatchTool( Path.GetDirectoryName( PatchUtils.GetCurrentExecutablePath() ), VERSION_INFO_URL );
			CheckForUpdates( patcher );

			Console.ReadLine();
		}

		private static void CheckForUpdates( SimplePatchTool patcher )
		{
			if( patcher.CheckForUpdates( false ) ) // false: each file is checked one-by-one to see if the app is up-to-date
			{
				WaitForPatcher( patcher );

				if( patcher.Result == PatchResult.AlreadyUpToDate )
					Console.WriteLine( "App is up-to-date!" );
				else if( patcher.Result == PatchResult.Failed )
					Console.WriteLine( "Operation failed..." );
				else
				{
					Console.WriteLine( "An update is available! Proceed? (y/n)" );
					if( Console.ReadLine().ToLowerInvariant() == "y" )
						ApplyPatch( patcher );
				}
			}
			else
				Console.WriteLine( "Looks like SimplePatchTool is busy (SimplePatchTool.IsRunning)" );
		}

		private static void ApplyPatch( SimplePatchTool patcher )
		{
			if( patcher.Run( true ) ) // true: self patching
			{
				WaitForPatcher( patcher );

				if( patcher.Result == PatchResult.AlreadyUpToDate )
					Console.WriteLine( "App is already up-to-date!" );
				else if( patcher.Result == PatchResult.Failed )
					Console.WriteLine( "Operation failed..." );
				else
				{
					Console.WriteLine( "App will restart itself to finalize the update. Hit Enter to proceed..." );
					Console.ReadLine();

					if( !patcher.ApplySelfPatch( PatchUtils.GetDefaultSelfPatcherExecutablePath( SELF_PATCHER_EXECUTABLE ), PatchUtils.GetCurrentExecutablePath() ) )
					{
						Console.WriteLine( "Something went wrong" );
						FetchLogs( patcher );
					}
				}
			}
			else
				Console.WriteLine( "Looks like SimplePatchTool is busy (SimplePatchTool.IsRunning)" );
		}

		private static void WaitForPatcher( SimplePatchTool patcher )
		{
			while( patcher.IsRunning )
			{
				FetchLogs( patcher );
				Thread.Sleep( 300 );
			}

			FetchLogs( patcher );
		}

		private static void FetchLogs( SimplePatchTool patcher )
		{
			IOperationProgress progress = patcher.FetchProgress();
			while( progress != null )
			{
				Console.WriteLine( string.Concat( progress.Percentage, "% ", progress.ProgressInfo ) );
				progress = patcher.FetchProgress();
			}

			string log = patcher.FetchLog();
			while( log != null )
			{
				Console.WriteLine( log );
				log = patcher.FetchLog();
			}
		}
	}
}
  • follow these steps and paste VersionInfo's url to the VERSION_INFO_URL constant
  • create a project
  • as this console app uses self patching, we need a self patcher: create a self patcher and put it inside the SelfPatcher directory of the project
  • enter the name of the self patcher's executable to the SELF_PATCHER_EXECUTABLE constant
  • create a subdirectory called 1.0 inside the Versions folder of the project
  • build the console app and move the generated files into the 1.0 subdirectory
  • follow these steps to create a patch (you can skip the Prerequisites)
  • you've created your first patch, great! Now, we should create a second patch to test the patcher. First, make some changes to the console app (e.g. increment the value of VERSION)
  • rebuild the console app and move its files to another subdirectory called 1.1 inside the Versions folder of the project
  • create another patch
  • if you launch the version 1.0 of your console app now, you'll see that it detects the 1.1 update and prompts you to update itself to that version, well done!
Clone this wiki locally