Как избежать одновременного запуска двух копий одного приложения
Такая задача возникает очень часто. Многие, особенно начинающие, пользователи не вполне понимают, что между щелчком по значку приложения и его запуском может пройти несколько секунд, а то и десятков секунд. Они начинают щелкать по значку, запуская все новые копии. Между тем, при работе с базами данных и во многих других случаях иметь более одной копии не только не нужно, но и вредно.
Идея заключается в том, чтобы первая создаваемая копия приложения захватывала некий, ресурс, а все последующие при запуске пытались сделать то же самое и в случае неудачи завершались.
Пример такого ресурса — общий блок в файле, отображаемом в память. Поскольку этот ресурс имеет имя, можно сделать его уникальным именно для вашего приложения:
var UniqueMapping : THandle;
FirstWindow : THandle
; begin
UniqueMapping := CreateFileMapping($ffffffff,
nil, PAGE_READONLY, 0, 32,'MyMap');
if UniqueMapping = 0 then
begin
ShowMessage(SysErrorMessage(GetLastError));
Halt;
end
else if GetLastError = ERROR_ALREADY_EXISTS then
begin
FirstWindow := FindWindowEx(0, 0, TfmMain.ClassName, nil);
if FirstWindowoO then
SetForegroundWindow(FirstWindow};
Halt;
end;
// Нет других копий — продолжение Application.Initialize;
Примерно такие строки нужно вставить в начало текста проекта до создания форм. Блок совместно используемой памяти выделяется в системном страничном файле (об этом говорит первый параметр, равный -1, см. описание функции CreateFileMapping). Его имя — муМар. Если при создании блока будет получен код ошибки ERROR_ALREADY__EXISTS, это свидетельствует о наличии работающей копии приложения. В этом случае приложение переключает фокус на главную форму другого экземпляра и завершается; в противном случае процесс инициализации продолжается.