Как обнаружить запущенную копию программы Delphi

Как обнаружить запущенную копию программы Delphi
Комментарии: 0

Рассмотрим способ обнаружения запущенного экземпляра программы на Delphi / Rad Studio. В случае обнаружения передадим ему команду на разворачивание из области уведомлений Windows (трей) и завершим работу второй копии.

Задача часто встречается на практике. Например, приложение, которое при закрытии сварачива в «Tray», при повторном запуске должно разворачиваться, а не запускать ещё одну копию.

Приступим к реализации:

  1. Открываем «Project Source» — в главном меню «Project - View Source».
  2. В раздел «uses» добавляем модуль «Windows» и объявляем две переменные типа «THandle».

    uses
      Forms,
      Windows,
      URealHoliday in 'URealHoliday.pas' {Form1};
    
    var xHand: THandle;
    var wnd: THandle;
    
  3. В тело вставляем код:

      xHand := CreateMutex(nil, True, 'unique_phrase');
      if (GetLastError = ERROR_ALREADY_EXISTS)or(GetLastError = ERROR_ACCESS_DENIED) then
      begin
        wnd := FindWindow('TForm1',nil);
        if wnd<>0 then
        begin
          SendMessage(wnd,WM_GOTOFOREGROUND,0,0);
        end;
    
        Application.Terminate;
        Exit;
      end;
    
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    

    Здесь сначала создаём «Mutex» с указанием какой-то уникальной фразы для приложения по которой сможем обращаться к ней. Если создание «Mutex» завершилось с ошибкой «ERROR_ALREADY_EXISTS» или «ERROR_ACCESS_DENIED», то почти наверняка экземпляр нашей программы уже запущен и можем текущий сеанс завершить. Но перед этим отправим запущенному процессу команду «WM_GOTOFOREGROUND», по которой основная форма должна разверуться поверх остальных окон Windows.

    Мутекс – это объект синхронизации потоков разных процессов. С его помощью можно синхронизировать совместный доступ нескольких процессов к одному файлу. Это делается так — создаётся «Mutex». Затем один из процессов становится его владельцем и начинает работу с файлом. После действий осовобождает «Mutex». Другие аналогичные процессы должны при работе с файлом также становиться владельцем мутекса и если это невозможно, то ждать своей очереди.

    «FindWindow» осуществляет поиск процесса по типу формы, поэтому вместо стандартного «TForm1» лучше использовать уникальное значение, но для примера оставим всё по-умолчанию.

Переходим ко второй части программы, в которой требуется отлавливать событие «WM_GOTOFOREGROUND» для совершения каких-то действий.

  1. Переходим в код основной формы. Облявляем константу после блока «Uses».

    const WM_GOTOFOREGROUND = WM_USER + 1;
    
  2. Объявляем публичную процедуру:

      public
        { Public declarations }
        procedure WMGotoForeground(var Msg:TMessage); message WM_GOTOFOREGROUND;
      end;
    
  3. Прописываем её код:

    procedure TForm1.WMGotoForeground(var Msg: TMessage);
    begin
     Form1.Visible := true;
     Application.Minimize;
     Application.Restore;
    end;
    

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

Такой вариант реализации взаимодействия процессов давно применяется не только в Delphi / Rad Studio. Возможно есть и другие более современные способы, особенно это касается нахождения дескриптора первого экземпляра программы. Буду рад если поделитесь ими.

Темы:
Delphi
Ещё интересное — 2
Комментарии —
    © REALADMIN.RU   2024 г.
    Страница сгенерирована: 0,1831 s | 4 mb.
    На каком уровне Вы играете в шахматы?
    OPROS