Как определить работает ли уже данное приложение или это его первая копия

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Сидит программист в столовой, обедает, суп ест. В очках такой, задумчивый, программу думает. Народу никого, все уже поели, ушли. Подходит к нему официантка и заигрывает:

— Если Вы хотите хорошо провести время, то меня зовут Маша!

Программист медленно возвращается на землю и смотрит на официантку отрешенным взглядом и на автопилоте спрашивает:

— А если не хочу, то как Вас зовут?!

Каждый экземпляр программы имеет ссылку на свою предыдущую копию — hPrevInst: hWnd. Ее можно проверить перед созданием приложения и при необходимости отреагировать соответствующим образом. Если запущена только одна копия, то эта ссылка равна нулю. Только для Delphi 1. Пример использования hPrevInst:

procedure TForm1.FormCreate(Sender: TObject);

begin

// Проверяем есть ли указатель на предыдущую копию приложения

if hPrevInst 0 then begin

// Если есть, то выдаем сообщение и выходим

MessageDlg(‘Программа уже запущена!’, mtError, [mbOk], 0);

Application.Terminate;

end;

// Иначе — ничего не делаем (не мешаем созданию формы)

end;

Другой способ — по списку загруженных приложений

procedure TForm1.FormCreate(Sender: TObject);

var

Wnd : hWnd;

buff : array[0.. 127] of Char;

begin

//Получили указатель на первое окно

Wnd := GetWindow(Handle, gw_HWndFirst);

// Поиск

while Wnd 0 do begin

// Это окно предыдущей копии ?

if (Wnd Application.Handle) and (GetWindow(Wnd, gw_Owner) = 0) then

begin

GetWindowText (Wnd, buff, sizeof (buff ));

if StrPas (buff) = Application.Title then

begin

MessageDlg(‘Приложение уже загружено’, mtWarning, [mbOk], 0);

Halt;

end;

end;

Wnd := GetWindow (Wnd, gw_hWndNext);

end;

end;

Данный пример не всегда применим — часто заголовок приложения меняется при каждом старте, поэтому рассмотрим более надежный способ — через FileMapping

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

program Project1;

uses

Windows, // Обязательно

Forms,

Unit1 in ‘Unit1.pas’ {Form1};

{$R *.RES}

const

MemFileSize = 1024;

MemFileName = ‘one_inst_demo_memfile’;

var

MemHnd : HWND;

begin

// Попытаемся создать файл в памяти

MemHnd := CreateFileMapping(HWND($FFFFFFFF),

nil, PAGE_READWRITE, 0, MemFileSize, MemFileName);

// Если файл не существовал запускаем приложение

if GetLastErrorERROR_ALREADY_EXISTS then

begin

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

end;

CloseHandle(MemHnd);

end.

Часто при работе у пользователя может быть открыто 5-20 окон и сообщение о том, что программа уже запущено приводит к тому, что он вынужден полчаса искать ранее запущенную копию. Выход из положения — найдя копию программы активировать ее, для чего в последнем примере перед HALT необходимо добавить строку : SetForegroundWindow(Wnd);

Пример:

program Project0;

uses

Windows, // !!!

Forms,

Unit0 in ‘Unit0.pas’ {Form1};

var

Handle1 : LongInt;

Handle2 : LongInt;

{$R *.RES}

begin

Application.Initialize;

Handle1 := FindWindow(‘TForm1’,nil);

if handle1 = 0 then

begin

Application.CreateForm(TForm1, Form1);

Application.Run;

end

else

begin

Handle2 := GetWindow(Handle1,GW_OWNER);

//Чтоб заметили 🙂

ShowWindow(Handle2,SW_HIDE); ShowWindow(Handle2,SW_RESTORE);

SetForegroundWindow(Handle1); // Активизируем

end;

end.

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

procedure TForm1.FormCreate(Sender: TObject);

var

hMutex : THandle;

begin

hMutex := CreateMutex(0, true , ‘My application name’);

if GetLastError = ERROR_ALREADY_EXISTS then

begin

CloseHandle(hMutex);

Application.Terminate;

end;

end;

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

{/codecitation}

Добавить комментарий