Архив рубрики: Software

C#: Добавить поддержку перезапуска приложения

В Windows есть возможность «зарегистрировать» приложение для перезапуска. Сделано это в основном с целью удобства для работы пользователя на случай установки обновлений компьютера. Т.е. в идеале, если приложение поддерживает функцию восстановления, то, после перезагрузки компьютера, оно снова будет запущено (при условии, что оно УЖЕ РАБОТАЛО перед перезагрузкой). Это не такая ресурсоёмкая процедура, как гибернация, т.к. на диск не сохраняются все участки оперативной памяти, с которыми работают приложения. Говоря простым языком, для восстановления сохраняются только ярлыки открытых программ, которые после перезагрузки заново запускаются.

Для работы нам потребуется доступ к функционалу Windows, под названием Application Recovery and Restart (ARR). По данной ссылке приведён пример на C++, при этом он довольно сложный и громоздкий.
Попробуем переделать его на C# (для простоты я приведу пример консольного приложения)…

Файл Program.cs

Сама программа, в которой мы производим регистрацию приложения для перезапуска. Сам класс для регистрации для удобства вынесен в отдельный файл, он приведён после основного.

Program.cs
namespace RestartManager
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				// Register with Restart Manager
				RestartManager.Register("--restarted", 0); // 0 = no flags
			}
			catch (Exception ex)
			{
				Console.WriteLine($"Registration failed: {ex.Message}");
			}

			// Check if the app was restarted
			if (args.Contains("--restarted"))
			{
				Console.WriteLine("Application was restarted!");
				// Add logic to restore state here
			}

			// Rest of your application code
			Console.WriteLine("Application is running...");
			Console.ReadKey();
		}
	}
}

Класс RestartManager.cs

Это вспомогательный класс, в котором как раз и используется API функция регистрации приложения.

RestartManager.cs
using System.Runtime.InteropServices;

namespace RestartManager
{
    public static class RestartManager
    {
		// Import the Windows API function
		[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern int RegisterApplicationRestart(
			[MarshalAs(UnmanagedType.LPWStr)] string pwzCommandline,
			RestartFlags dwFlags
		);

		// Flags to control restart behavior (optional)
		[Flags]
		public enum RestartFlags : uint
		{
			RESTART_NO_CRASH = 1,
			RESTART_NO_HANG = 2,
			RESTART_NO_PATCH = 4,
			RESTART_NO_REBOOT = 8
		}

		// Wrapper method for easier use
		public static void Register(string commandLineArgs, RestartFlags flags)
		{
			int result = RegisterApplicationRestart(commandLineArgs, flags);
			if (result != 0)
			{
				// Throw an exception with the Win32 error code
				int errorCode = Marshal.GetLastWin32Error();
				throw new System.ComponentModel.Win32Exception(errorCode);
			}
		}
	}
}

Применение

Если мы запустим приложение, в консоль будет выведена строка:

Application is running...

После этого, ничего не закрывая, перезагрузим компьютер (можно просто завершить сеанс пользователя и зайти заново). После перезагрузки наше приложение будет снова запущено автоматически. На этот раз там будут выведены две строчки:

Application was restarted!
Application is running...