Форум: "Основная";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
ВнизКак определить запущена ли программа... Найти похожие ветки
← →
maxXP © (2004-03-18 22:18) [0]Как определить запущена ли программа, для блокировки её повторного запуска?
← →
Mox Fulder © (2004-03-18 22:22) [1]Я читал, что создаётся какой-то MUTEX с уникальной строкой. При запуске проверка: если мутекс существует, завершаемся, иначе - работает, создавая мутекс. Я не проверял. Как делат - не знаю, просто вычитал где-то....
← →
maxXP © (2004-03-18 22:25) [2]А я точно знаю, что через хэндал можно определить, но потерял исходники :(
← →
Mox Fulder © (2004-03-18 22:28) [3]Тогда ищи приложение по классу окна. FindWindow(nil,"типа мой класс"), по-моему...
← →
Mox Fulder © (2004-03-18 22:32) [4]То-есть наоборот FindWindow("типа мой класс",nil)
Класс смотри в WinSight32 в комплекте делфи. Нади своё приложение, там пишется класс.
← →
Mox Fulder © (2004-03-18 22:36) [5]Ещё: если у тебя в проэкте
Аpplication.CreateForm(TForm1, Form1);
то TForm1 - это и есть класс по-моему....
← →
maxXP © (2004-03-18 22:44) [6]Был еще какой-то способ, был *(
← →
Mox Fulder © (2004-03-18 22:53) [7]А чем этот не устраивает?
Procedure TForm1.Create(Sender:TObject);
begin
...
If FindWindow("TForm1",nil) then Application.Terminate
end;
Вроде так...
← →
Mox Fulder © (2004-03-18 22:56) [8]Проверил. Раотает это:
procedure TForm1.FormCreate(Sender: TObject);
var a:thandle;
begin
a:=FindWindow("TForm1",nil);
if a<>0 then Application.Terminate;
end;
end.
ЗЫ: Дурная привычка: написать, потом подумать.
← →
Alexander666 © (2004-03-19 06:32) [9]Вообще-то лучше всего использовать мьютексы, тем более, что это очень просто. Некоторые используют глобальные атомы. Ну и собственно статейка: http://www.delphimaster.ru/articles/limit.html
← →
y-soft © (2004-03-19 07:59) [10]Насчет статьи - код в общем-то демонстрационный, для дальнейшего творческого осмысливания :)
Т.к. в качестве уникальной строки используется путь к приложению, то ничто не мешает запустить тот же файл из другой директории, или, например, переименованную копию exe
Если это важно, то лучше в качестве такой строки использовать, например, специально сгенерированный для приложения GUID...
Часто предлагают также скомбинировать объекты ядра и поиск по заголовку и классу окна. Т.е. вместо мьютекса использовать объект FileMapping, в который программа, запущенная первой, записывает Handle своего главного окна. Соответственно, следующие копии выводят это окно на передний план. Но тут упускается сразу несколько моментов:
Во-первых - между созданием FileMapping и созданием окна произойдет довольно значительное время. Если второй экземпляр приложения запустится в этот промежуток времени, то хендл окна записан еще не будет, а значит и окно первого экземпляра на передний план вывести будет невозможно
Во-вторых - такой подход нельзя использовать для "безоконных" приложений
В-третьих - начиная с Windows 2000, Microsoft изменила правила для функций перемещения окон на передний план, вместо того, чтобы поместить окно на передний план, ОС заставляет мигать кнопку на панели задач (подробнее см. http://www.rsdn.ru/article/qna/ui/wndsetfg.xml)...
Вот перевод хорошей статьи по subj:
http://www.rsdn.ru/article/baseserv/avins.xml
← →
Юрий Зотов © (2004-03-19 10:42) [11]Насчет FindWindow в этой задаче.
От момента старта программы до момента создания ею своего первого окна проходит заметное (а иногда и очень большое) время. Время это зависит как от самой задачи (операций, выполняемых на этапе инициализации), так и от других работающих в системе задач. Причем ясно, что проверка существования окна должна быть выполнена именно на участке инициализации.
Теперь представим себе ситуацию, когда 2 копии программы запускаются одна за другой с очень малым интервалом времени. В этом случае вторая копия запросто может и не обнаружить окна первой копии, поскольку его еще действительно нет (первая копия просто еще не успела его создать. Результат - обе копии будут работать.
Поэтому все методы идентификации второй копии, основанные на поиске окна имеют низкую надежность и потому, фактически, неприемлемы и нужно использовать проверку по другим уникальным объектам, которые могут (и должны!) быть созданы немедленно после старта программы. В частности, это могжет быть глобальный объект ядра (memory mapped file, мьютекс, семафор, атом и пр.).
Если есть сомнения в сказанном - напишите тестовую программку с проверкой второй копии через FindWindow, а затем быстро-быстро многократно щелкайте по ее EXE-файлу в Проводнике. Еще хуже, если программа регистрирует свой тип файлов, при запуске открывает файл(ы) из командной строки и, если это не первая копия, то передает открываемые файлы первой, а сама завершается (а-ля MS Word). Как показала одна недавняя ветка, если в Проводнике выделить несколько файлов и дать команду "открыть", то вместо одной командной строки вида
MyProg.exe MyFile1 MyFile2 ... MyFileN
Проводник генерирует N командных строк вида
MyProg.exe MyFile1
MyProg.exe MyFile2
...
MyProg.exe MyFileN
В этой ситуации промежуток времени между стартами копий ОЧЕНЬ мал и если проверка сделана через FindWindow, то описанная выше ситуация практически гарантирована.
← →
y-soft © (2004-03-19 11:06) [12]>Юрий Зотов © (19.03.04 10:42) [11]
Юрий, насчет атомов Вы наверное оговорились :)
Есть у глобальных атомов одна крайне непрятная особенность - без явного освобождения они остаются в системе до ее перезагрузки :(
Т.е. если приложение, использующее для идентификации глобальный атом аварийно завершится, то его не удастся повторно запустить до этой самой перезагрузки ОС.
Объекты же ядра при любом завершении процесса освобождаются гарантированно...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.038 c