Запрет запуска второго экземпляра программы

Не знаю почему, но у многих возникает вопрос, как предотвратить запуск второго экземпляра запущенной программы. А ведь эта задача довольно-таки тривиальная.

Итак, запретить запуск второго экземпляра программы можно несколькими способами. Первый- это использование мутексов.

Мутекс – это объект синхронизации, который находится в сигнальном состоянии только тогда, когда он не принадлежит ни одному из процессов. Как только хотя бы один процесс запрашивает владение мутексом, он переходит в несигнальное состояние и остается в нем до тех пор, пока не будет освобожден владельцем.

Теперь учитывая это определение, мы можем применить его на практике. Создадим новый проект и назовем его Mutex. На форме я ничего не буду отображать, да и нет в этом смысла. Мы же запрещаем запуск программы, не так ли?

Теперь в разделе program пишем следующий код. Этот раздел отвечает за запуск всех наших форм и т.д.

program Mutex;

uses
  Forms, Windows, Dialogs, Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
Var
hMutex:THandle;
begin
//Создаем мутекс
  hMutex:=CreateMutex(Nil,true,'Unigue Mutex'); 
  if GetLastError = ERROR_ALREADY_EXISTS then
    begin
      ShowMessage ('Программа уже запущена');
      Application.Terminate;
    end;
 ReleaseMutex (hMutex); // освобождаем Mutex
  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

Все, теперь можно скомпилировать и запустить нашу программу. Запустите вторую копию программы и увидите сообщение. Все, наша задача решена.

Мутексы очень полезный инструмент межпроцессного взаимодействия. О нем я часто буду говорить в разделе С++. Просто если вы программируете в C++ Bulder или VC++, то там используется почти тот же подход (особенно в C++ Bulder).

Второй способ более прозаичен и понятен. Нам нужно будет получить хендл открытого окна приложения, сравниваем хендл новой проги и закрываемся, если он совпадает. В общем,

можете использовать предыдущий проект, вот только сотрите код с мутексом. В принципе, можете стереть все и написать следующий код:

program Mutex;

uses
  Forms,Windows,Dialogs,
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
Var
hnwd: HWND;
begin
//получаем дескриптор
hnwd:=FindWindow('Mutex',nil);
if (hnwd<>0) then  //нашли окно
    begin
      ShowMessage ('Программа уже запущена!');
      SetForegroundWindow (hnwd);
      Application.Terminate; //закрываемся
    end;

  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

Здесь самая загвоздка в том, что нам нужно точно знать класс нашего окна. Для этих целей нужно применять какой-нибудь winspy. Несмотря на то, что данный способ тоже работает, мне он меньше нравится (хотя бы потому, что часто косячу с классом окна). Тем не менее, можете выбирать сами понравившийся.

К этим двум способам можно добавить и третий. Он использует atom. Но это уже для более крутых программистов. Лично я с ним не заморачиваюсь. Думаю, что и вам он не нужен.

Вот мы с вами сегодня научились, как можно предотвратить запуск второго экземпляра программы. Немного подшаманить код и он будет работать и в других языках. Если же вы используете С#, то там данная задача решается значительно проще. Но об этом мы поговорим в других статьях.

Вячеслав “VeGA” Головлев.

При копировании ссылка на www.programbeginner.ru обязательна


Яндекс.Метрика