Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как не допустить запуск второй копии программы 8

Delphi , Программа и Интерфейс , Приложение своё

Как не допустить запуск второй копии программы 8

Программистские проекты бывают трех основных типов:
1. Неудачный проект первого рода - когда не удалось заключить контракт.
2. Неудачный проект второго рода - когда удалось заключить контракт.
3. Удачный проект, или проект с предоплатой.

Предоставленное разработчиками Delphi 2 Пачекой (Pacheco) и Тайхайрой (Teixeira) и значительно переработанное.


unit multinst;
{

Применение:
Необходимый код в исходном проекте

if InitInstance then
begin
Application.Initialize;
Application.CreateForm(TFrmSelProject, FrmSelProject);
Application.Run;
end;
Это все понятно (я надеюсь)
}

interface

uses Forms, Windows, Dialogs, SysUtils;

const

  MI_NO_ERROR = 0;
  MI_FAIL_SUBCLASS = 1;
  MI_FAIL_CREATE_MUTEX = 2;

  { Проверка правильности запуска приложения с помощью описанных ниже функций. }
  { Количество флагов ошибок MI_* может быть более одного. }

function GetMIError: Integer;
function InitInstance: Boolean;

implementation

const

  UniqueAppStr: PChar; {Различное для каждого приложения}

var

  MessageId: Integer;
  WProc: TFNWndProc = nil;
  MutHandle: THandle = 0;
  MIError: Integer = 0;

function GetMIError: Integer;
begin

  Result := MIError;
end;

function NewWndProc(Handle: HWND; Msg: Integer; wParam,

  lParam: Longint): Longint; stdcall;
begin

  { Если это - сообщение о регистрации... }

  if Msg = MessageID then
  begin
    { если основная форма минимизирована, восстанавливаем ее }

{ передаем фокус приложению }
    if IsIconic(Application.Handle) then
    begin
      Application.MainForm.WindowState := wsNormal;
      ShowWindow(Application.Mainform.Handle, sw_restore);
    end;
    SetForegroundWindow(Application.MainForm.Handle);
  end
    { В противном случае посылаем сообщение предыдущему окну }
  else
    Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;

procedure SubClassApplication;
begin

  { Обязательная процедура. Необходима, чтобы обработчик }
  { Application.OnMessage был доступен для использования. }
  WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
    Longint(@NewWndProc)));
  { Если происходит ошибка, устанавливаем подходящий флаг }
  if WProc = nil then
    MIError := MIError or MI_FAIL_SUBCLASS;
end;

procedure DoFirstInstance;
begin

  SubClassApplication;
  MutHandle := CreateMutex(nil, False, UniqueAppStr);
  if MutHandle = 0 then
    MIError := MIError or MI_FAIL_CREATE_MUTEX;
end;

procedure BroadcastFocusMessage;
{ Процедура вызывается, если уже имеется запущенная копия Вашей программы. }
var

  BSMRecipients: DWORD;
begin
  { Не показываем основную форму }

  Application.ShowMainForm := False;
  { Посылаем другому приложению сообщение и информируем о необходимости }
  { перевести фокус на себя }
  BSMRecipients := BSM_APPLICATIONS;
  BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
    @BSMRecipients, MessageID, 0, 0);
end;

function InitInstance: Boolean;
begin

  MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr);
  if MutHandle = 0 then
  begin
    { Объект Mutex еще не создан, означая, что еще не создано }

{ другое приложение. }
    ShowWindow(Application.Handle, SW_ShowNormal);
    Application.ShowMainForm := True;
    DoFirstInstance;
    result := True;
  end
  else
  begin
    BroadcastFocusMessage;
    result := False;
  end;
end;

initialization
  begin

    UniqueAppStr := Application.Exexname;
    MessageID := RegisterWindowMessage(UniqueAppStr);
    ShowWindow(Application.Handle, SW_Hide);
    Application.ShowMainForm := FALSE;
  end;

finalization
  begin

    if WProc <> nil then
      { Приводим приложение в исходное состояние }

      SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
  end;
end.

Программный код, который вы предоставили, - это программу на Delphi, которая предназначена для предотвращения запуска нескольких экземпляров приложения одновременно. Она использует механизмы Windows API Mutex и WindowMessage для достижения этого.

Вот подробное описание того, что код делает:

  1. Функция InitInstance инициализирует экземпляр приложения. Если уже запущен другой экземпляр того же приложения, она возвращает False. В противном случае, она создает мьютекс с именем, соответствующим имени исполняемого файла приложения.
  2. Процедура DoFirstInstance вызывается, если это первый запущенный экземпляр приложения. Она подклассирует процедуру окна приложения для захвата сообщений и настраивает фильтр сообщений для обнаружения запуска другого экземпляра того же приложения.
  3. Если обнаружен другой экземпляр того же приложения, процедура BroadcastFocusMessage отправляет сообщение этому экземпляру, запросив его сфокусироваться (то есть, принести главное окно в передний план).
  4. Функция NewWndProc обрабатывает сообщения, отправленные процедурой окна приложения. Если она получает сообщение, указывающее на запуск другого экземпляра того же приложения, она восстанавливает главное окно и устанавливает фокус.

Чтобы предотвратить запуск нескольких экземпляров, вы можете использовать следующий подход:

  1. Проверьте, существует ли мьютекс, созданный в DoFirstInstance, перед его созданием.
  2. Если мьютекс существует, это означает, что уже запущен другой экземпляр того же приложения, поэтому возвращает False из InitInstance.
  3. Если мьютекс не существует, создайте его и продолжите процесс инициализации.

Вот пример, как можно модифицировать код для достижения этого:

function InitInstance: Boolean;
begin
  if OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr) <> 0 then
    Exit(False);

   // Остальная часть кода инициализации...
end;

Таким образом, если уже запущен другой экземпляр того же приложения, InitInstance вернет False, предотвратив запуск текущего экземпляра.

Обратите внимание, что этот подход предполагает, что мьютекс, созданный в DoFirstInstance, не будет удален до тех пор, пока приложение не будет закрыто. Вы можете достичь этого, переместив вызов CloseHandle(MutHandle) в раздел Finalization единицы, после того как переменная WProc будет установлена в nil.

Как не допустить запуска второй копии программы: код на Delphi для предотвращения одновременного запуска приложения.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Приложение своё ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 12:09:31/0.0059630870819092/1