Нашел в интернете много способов реализации на запрет запуска второго экземпляра приложения. Выбрал самый на мой взгляд минималистский. Я думаю, может многим понадобится — вообще применяется это достаточно часто.
Итак, нужно открыть исходный код главного файла проекта (меню Project — View Source). В секцию uses добавляем библиотеки Windows и Dialogs:
uses
...
Windows,
Dialogs,
...
В секцию Var (переменные, если нет такой — создаем):
var
H: THandle;
Теперь, непосредственно перед строкой:
Application.Initialize;
Добавим нашу проверку, не запущен ли уже другой экземпляр программы:
H := CreateMutex(nil, True, 'уникальная фраза');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
showmessage('Программа уже работает!');
Exit;
end;
‘уникальная фраза’ — это что-то например «и64ерм9со46к79826о» — в общем то, что наверняка будет использовать только Ваша программа. Можно также использовать,например, название программы.
Еще надо добавить
var H: Cardinal;
Да, забыл объявить переменную, Вы в этом правы. Но я использовал тип THandle, насчет Cardinal — не проверял. Статью поправил, спасибо!
Разницы нет, что THandle, что Cardinal, оба типа — это числа по 4 байта
Привет! (Сразу к делу) Я читал Ваши статьи и узнал, что Вы программируете свои приложения в среде разработки Delphi. Вы не подскажете (исходный код) как открывать все формы на одном окне? (Например: открывание Form2 в Form1)… Заранее благодарен! И спасибо большое за программу TurboSite!
Привет. Не совсем понял что имеется ввиду. Если Ваш нужно в одном окне показывать разное содержимое, то можно использовать PageControl со скрытыми вкладками, которые Вы сами програмно будете переключать.
Спасибо за ответ, но я уже нашел ответ (в интернете). =)
Добавляю
H := CreateMutex(nil, True, PChar(Application.Title));
if GetLastError = ERROR_ALREADY_EXISTS then
begin
showmessage(‘Программа уже работает!’);
SetForegroundWindow(FindWindow(nil, PChar(Application.Title))); // помещаем окно с уже запущенной программой на передний план
Exit;
end;
перед строкой
Application.Initialize;
и кнопка Run перестает быть активной, как быть?
O_o
удивило
если даже в коде ошибка — кнопка из-за этого не может стать не активной. Проверьте внимательно, в этом ли причина.
Через run итак только одна копия запускается) заходи папку с проектом и открой exe файл два раза
Та же фигня, что у baur, лечится заменой Application.Title на что-нибудь, не обращающееся к Application (я просто подставил строку).
Тоже вариант. Application.Title я выбрал в качестве идентификатора программы. Надежнее всего будет вместо него использовать строку со случайным набором символов, который с наименьшей вероятностью будет использовать другое приложение.
Если надо как-то привязатья к названию программы (файла), то надо использовать PChar(ExtractFileName(ParamStr(0)))
Т.к. при запуске файла у него по умолчанию в качестве нулевого параметра передается имя файла
Да также беда. Delphi 7.
А подскажите тогда чем можно заменить Title ?
плохой способ
Application.Title не может быть использован пока не проинициализируется,
лучше использовать FindWindow
я сделал вот так
var H: THandle;
…
H := FindWindow(‘TMainForm’, ‘MainForm’);
if H 0 then
begin
showmessage(‘Программа уже работает!’);
Exit;
end;
Application.Initialize;
где «MainForm» ваше главное окно, но в этом методе есть заковыка наименование вашего окна должно быть уникальным для всех используемых приложений в Windows
Заменил application.title на ‘уникальную фразу’.
Отлично. Понадобилось. У меня уже не раз эта проблема возникала и я ее никак не мог решить. Всегда старался ее обойти, но это не очень приятно.
Если это в событие CreateForm поместить, то messagebox появляется. но почему-то не выходит на Exit, а продолжает работу.
Все правильно, происходит Exit из процедуры OnCreateForm, а не из программы.
Чтобы надежно завершить — надо вместо exit набрать halt (жесткое завершение) или Close. Но с процедурой halt надо аккуратно, потому что она убивает приложение, но могут быть потеряны куски памяти.
Ну или как-то по другому, мягко завершить программу
И кстати, не знаю, важно это или нет, но код надо доработать, а именно, перед Exit надо бы добавить CloseHandle(H), а в самом конце (после Application.Run) надо добавить строчку ReleaseMutex(H).
Почему это важно: если Вы не просто закрываете вторую программу, а ждете завершения первой, то вторая программа не запустится даже после закрытия первой.
я бы Exit; заменил на halt; чтобы сразу отрубалась 2-я копия, без головняков 🙂