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 May 24, 2019 · 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 following:
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";

		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();

					string rootPath = Path.GetDirectoryName( PatchUtils.GetCurrentExecutablePath() );
					string selfPatcherPath = Path.Combine( PatchParameters.SELF_PATCHER_DIRECTORY, "SelfPatcher.exe" );
					if( !patcher.ApplySelfPatch( Path.Combine( rootPath, selfPatcherPath ), 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 executable: create a self patcher executable and put it inside the SelfPatcher directory of the project
  • create a subdirectory called 1.0 inside the Versions directory of the project
  • build the console app and move the generated executables and libraries into the 1.0 subdirectory
  • follow these steps to create a patch, upload it to the server, update download links in VersionInfo and etc.
  • you've created your first patch, great! We should now 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 directory of the project
  • create another patch following these steps
  • if you launch the 1.0 version of your console app now, you'll see that it'll detect the 1.1 update and prompt you to update itself to that version, well done!
Clone this wiki locally