Статьи Королевства Дельфи

         

Прошло некоторое время, клавиатура остыла


Hello, MiniProg 2
Раздел Подземелье Магов
Продолжение, .

Прошло некоторое время, клавиатура остыла после тестирования и писательства, можно продолжать.
Попробуем сделать так, что бы программа следила за тем, что бы она была запущена в единственном экземпляре. Пока мы не углубились в обсуждение деталей реализации, хотелось бы объяснить, для чего такое "суровое" требование единственности и неповторимости. Дело в том, что если пользователям удобнее использовать одновременно несколько копий одной и той же программы, то это верный признак того, что изначально был спроектирован неверный интерфейс, скорее всего больше подошел бы MDI. Это первое, второе - считается, что чаще всего запуск второй копии происходит по ошибке, когда приложение свернуто и его просто не видно.

Данная тема уже не раз поднималась на просторах , например, или . Огромное множество материала, на данную тематику, чьей то щедрой рукой, разбросано по интернету. Правда, все методы однотипные и сводятся к тому, что программа, при запуске, проверяет какой-нибудь признак, если он не обнаружен - то запускается, если же присутствует... В этом месте возможны самые различные реакции, от сообщений, с требованием ответа/нажатия кнопки, до коварнейших систем оповещения создателей (например, как у M$ XP :). Признаком может служить, либо проверка наличия определенного окна, либо отметка в конфигурационном файле/регистре, либо банальный файл, создаваемый при запуске приложения и удаляемый при выходе из него. Более сложные системы, профессионального уровня, обращаются за советом, "можно, или нельзя", к специализированным лицензионным серверам.
Мы пойдем другим путем, наверное, самым простым, будем проверять наличие определенного мьютекса, реакция же будет вежливая - просто активизация окна. Данный метод не нов. Определенно, он работоспособен, но не мешало бы создать тест, который бы нас убедил, что это так. И это еще одна рекомендация XtremeProgramming - не лениться и стараться тестировать как можно больше. Вообще, если бы программисты знали, как много ошибок может быть, в казалось бы, в надежном и простом коде: Откроем testMiniProg.dpr и в файле testAppl.pas создадим следующую процедуру:

Const StrFailedTest = 'failure test'; ... procedure TTestUnitAppl.TestFindPrevInstance; var Test1, Test2: boolean; Temp: THandle; begin Temp := Mutex; Test1 := not FindPrevInstance('Test'); Test2 := FindPrevInstance('Test'); StopPrevInstance; Check(Test1 and Test2, strFailedTest); Mutex := Temp; end;
Сами функции располагаются в Appl.pas и выглядят так:

Var Mutex: THandle = 0; ... function FindPrevInstance(Name: string): boolean; var Temp: THandle; begin Temp := CreateMutex(nil, False, PChar(Name)); Result := (GetLastError = ERROR_ALREADY_EXISTS); if Result then CloseHandle(Temp) else Mutex := Temp; end; procedure StopPrevInstance; begin if Mutex > 0 then CloseHandle(Mutex); end;

Содержание  Назад  Вперед