Ранее я уже писал заметку «WPF: Запускать только одну копию приложения«. Было это, как оказалось, довольно «давно». Хоть и прошло всего полтора года, а часть ссылок уже недоступна и некоторые пункты контекстного меню изменились. Попробуем сделать аналогичное приложение немного другим способом.
Подключение пакета SingleInstanceCore
0. У нас уже должен быть открыт пустой проект WPF и здесь я не расписываю пошагово, как именно его нужно создавать.
1. Для начала нам нужно добавить в проект пакет «SingleInstanceCore» (этот пакет из состава NuGet, поэтому на этот раз нам пригодится пункт главного меню Visual Studio Community: NuGet Package Manager).
Хотя, данный пакет можно поставить и через NuGet Package Manager Console
Install-Package SingleInstanceCore -Version 2.2.0
2. Убедимся, что пакет был добавлен в проект, для чего раскроем дерево проекта на пункте
3. Если приложение вызывается с аргументами, то мы их должны обрабатывать при каждом вызове (файл App.xaml.cs):
public partial class App : Application, ISingleInstance
{
public void OnInstanceInvoked(string[] args)
{
//Здесь обрабатываются аргументы, которые передали приложению
// Например так:
// https://docs.microsoft.com/ru-ru/dotnet/api/system.windows.application.startup?view=net-5.0
}
// Что-то ещё
}
Чтобы не было ошибок, нужно добавить в начало файла строку:
using SingleInstanceCore;
4. В тот же файл добавим строчки для инициализации данного экземпляра приложения:
private void Application_Startup(object sender, StartupEventArgs e)
{
bool isFirstInstance = this.InitializeAsFirstInstance("soheilkd_ExampleIPC");
if (!isFirstInstance)
{
//If it's not the first instance, arguments are automatically passed to the first instance
//OnInstanceInvoked will be raised on the first instance
//You may shut down the current instance
Current.Shutdown();
}
}
5. Чуть ниже не забудем добавить метод для очистки памяти при выходе из приложения:
private void Application_Exit(object sender, ExitEventArgs e)
{
//Do not forget to cleanup
SingleInstance.Cleanup();
}
6. Далее нам нужно обратить внимание на файл App.xaml, здесь свойство StartupUri замещается подпиской на событие Startup, т.о. полный код этого файла теперь будет такой:
<Application x:Class="SingleInstanceApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SingleInstanceApp"
Startup="Application_Startup">
<Application.Resources>
</Application.Resources>
</Application>
Теперь при запуске приложения будет произведена проверка и, если это приложение уже было запущено ранее, то новое окно не будет открыто (процесс будет убит).
Другой метод, в котором мы восстанавливаем состояние окна, если запущено новый процесс, описан тут.
Другой вариант
Этот вариант более простой в реализации, т.к. требует изменения только файла App.xaml.cs.
using System.Threading;
using System.Windows;
namespace SingleInstanceAppDemo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private static Mutex? _mutex;
// Allow only one instance at a time
protected override void OnStartup(StartupEventArgs e)
{
const string appName = "SingleInstanceAppDemo";
_mutex = new Mutex(true, appName, out bool createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
base.OnStartup(e);
}
}
}
- Не приходит СМС для авторизации на сайте Госуслуги - 01.11.2024
- VSCode: Найти и удалить элементы xml - 29.10.2024
- WordPress: Ошибка в плагине WpDiscuz - 08.10.2024