Форум: "WinAPI";
Текущий архив: 2002.05.16;
Скачать: [xml.tar.bz2];
ВнизБлокировка повторного запуска приложения Найти похожие ветки
← →
NY152 (2002-01-29 14:03) [0]Люди добрые, подскажите как проверить наличие копии программы в памяти чтобы исключить её повторный запуск ? В инете есть куски кода - но все они какие-то очень сложные, может кто пользуется чем-то уже давно, дайте процедурку =)
Заранее благодарен.
ПС: заранее прошу прощения, наверное уже были подобные вопросы, но я что-то не нашёл их, подскажите тогда ссылку =)
← →
Бильврёст (2002-01-29 14:21) [1]Это очень просто реализуется с помощью мьютексов - посмотрите help - там всё очень доступно.
← →
serg001 (2002-01-29 14:22) [2]Вот главная прога:
programtvojaprogramma
;
uses thefirst...
...
Вот юнит thefirst:
unit thefirst;
interface
implementation
uses
Windows;
var
Mutex : THandle;
MutexName : array[0..255] of Char;
function StopLoading : boolean;
var
L,I : integer;
begin
// В качестве уникального имени мьютекса используем полный путь
// к исполняемому файлу приложения
L := GetModuleFileName(MainInstance,MutexName,SizeOf(MutexName));
// В имени мьютекса нельзя использовать обратные слэши, поэтому
// заменяем их на прямые
for I := 0 to L - 1 do
if MutexName[I] = "\" then
begin
MutexName[I] := "/";
end;
Mutex := CreateMutex(nil,false,MutexName);
Result := (Mutex = 0) or // Если мьютекс не удалось создать
(GetLastError = ERROR_ALREADY_EXISTS); // Если мьютекс уже существует
end;
initialization
if StopLoading then halt;
finalization
if Mutex <> 0 then
CloseHandle(Mutex);
end.
← →
Valentin2 (2002-01-29 14:38) [3]program Project1;
uses
Forms,Windows,
Unit1 in "Unit1.pas" {Form1};
const NamedMutex="OneOnly";
var
MT:Integer;
function CheckInstance(Name:PChar):Integer ;
var
r:integer;
Mutex:Integer;
begin
Mutex:=CreateMutex(nil,true,Name);
r:=GetLastError();
if (r<>0)
then Result:=0
else Result:=Mutex;
end;
{$R *.RES}
begin
MT:=CheckInstance(NamedMutex);
if (MT=0) then
begin
MessageBox(0,"Приложение уже запущено","Ошибка",0);
exit;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
← →
panov (2002-01-29 14:42) [4]А еще проще FAQ посмотреть, и статьи почитать...
← →
erik (2002-01-29 15:18) [5]Я использую GlobalAtom мне кажнтся так проще и ресурсрв меньше идет.
← →
panov (2002-01-29 15:29) [6]Эта тема неоднократно обсуждалась. Практически ни один метод не дает 100% гарантии...
← →
Johnmen (2002-01-29 16:24) [7]>>>panov © ты неправ, система семафоров однозначно определяет, запущен ли процесс...
>>>NY152 : самое простое и надежное :
// second instance ?
SetLastError(0);
CreateSemaphore(nil,0,1,"YourSemaphoreName");
if GetLastError<>0 then begin;
MessageDlg("ПРОГРАММА УЖЕ ЗАПУЩЕНА !",mtError,[mbOk],0);
Halt(1);
end;
где YourSemaphoreName уникальное имя твоего семафора...
← →
amamed_3071 (2002-01-29 16:58) [8]В Source пройекта прибав....
Var x:Hwnd;
Begin
Application.Initialize;
Application.Title:="TMPTitle";
x:=Findwindow(nil,"Application Title");
if x<>0 then
Begin
ShowWindow(x,SHOW_OPENWINDOW);
SetForegroundWindow(X);
Halt;
End;
Application.Title := "Application Title";
Application.CreateForm..
....
End.
← →
Raptor (2002-01-29 22:02) [9]Уже в который раз поднимается этот вопрос, и всегда по нему много споров. :-))
Приведу адрес очень хорошей и полной статьи посвященной этой проблеме. Всем, кого это интересует, советую прочитать ее и тогда все вопросы будут сняты.
http://www3.pgh.net/~newcomer/nomultiples.htm - оригинал.
http://www.rsdn.ru/article/?baseserv/avins.xml - перевод.
← →
panov (2002-01-30 07:01) [10]>Johnmen © (29.01.02 16:24)
В чем не прав? Если не прав, то поправь:
Никакой гарантии.
Со времени старта программы до установки семафора проходит некоторое время. Согласен?
В это время успешно может стартовать та же самая программа.
Может быть, с этим не согласен?
← →
Алексей Петров (2002-01-30 08:02) [11]> panov © (30.01.02 07:01)
> Никакой гарантии.
Ты не прав. CreateSemaphore и ей подобные выполняются ядром последовательно и выставляют GetLastError в 0, если объект действительно создан или в ERROR_ALREADY_EXISTS, если объект был создан ранее а сейчас только открыт.
При этом 2 процесса не могут получить GetLastError=0 при создании объекта с одним именем.
← →
panov (2002-01-30 09:57) [12]Признаю ошибку.
Согласен.:-)
← →
Юрий Зотов (2002-01-30 15:05) [13]> В это время успешно может стартовать та же самая программа.
Стартовать-то она может, ну и что? Пусть себе стартует.
Но затем она попытается создать объект ядра, а в ответ получит ERROR_ALREADY_EXISTS и завершится, ничего не сделав. Что и требовалось.
← →
copyr25 (2002-01-30 20:40) [14]Однажды я делал ScreenSaver и, понятное дело, натолкнулся на то же.
Вот код, который безупречно работает:
...
var
myAtom:Atom;
...
procedure TForm1.FormCreate(Sender: TObject);
var ia:ATOM;
begin
ia:=GlobalFindAtom("MyOwnAtom");
if (ia<>0) then halt(0);
myAtom:=GlobalAddAtom("MyOwnAtom");
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
GlobalDeleteAtom(myAtom);
end;
"Manaenkov Paul" <paulmank@hotmail.com>
← →
copyr25 (2002-01-30 20:47) [15]Т.е. "Manaenkov Paul" <paulmank@hotmail.com>
это автор кода, который любезно предложил мне его на мой
призыв о помощи...
← →
Fellomena (2002-02-05 13:44) [16]2 Johnmen © (29.01.02 16:24)
>>>panov © ты неправ, система семафоров однозначно определяет, запущен ли процесс...
Хех... а семафор от мьютекса отличается лишь тем, что семафорами можно варьировать кол-во запущенных экземпляров, тогда как мьютекс это тот же семафор, только кол-во экземпляров всегда равно 1 - вот.
← →
Johnmen (2002-02-05 15:03) [17]>>>Fellomena : ...только кол-во экземпляров всегда равно 1 ...
экземпляров чего ?
← →
Fellomena (2002-02-06 15:05) [18]2 Johnmen:
Как это чего ? 8)
В нашем конкретном случае ПРОЦЕССА, но можно таким образом и thread-ы синхронизировать в процессе - разницы не много.
Ведь создаваемый семафор или мьютекс, как я понимаю, объект глобальный, т.е., наверное, рассполагается не в АП процесса из которого он был установлен, а в куче самого Win, хотя он (семафор или мьютекс)
связан с породившим процессом, т.е. при завершении работы процесса мьютекс уничтожается 8)
Наверное так...
← →
Johnmen (2002-02-06 15:22) [19]>Fellomena : я не совсем понял, что конкретно ты хотел сказать
(Fellomena (05.02.02 13:44)), но высказывания в (Fellomena (06.02.02 15:05)) в целом верны :)
← →
Керик (2002-02-07 05:00) [20]Я делаю так:
var
UniqueMapping: THandle;
...
UniqueMapping := CreateFileMapping($ffffffff, nil, PAGE_READONLY, 0, 32, "Имя программы");
if UniqueMapping = 0 then
begin
Application.MessageBox("Ошибка выделения памяти!",
"Ошибка", mb_IconError+mb_Ok);
Halt;
end
else if GetLastError = ERROR_ALREADY_EXISTS then
begin
Application.MessageBox("Вы запускаете програму второй раз! Работать не буду :-)", "Ошибка!", mb_IconInformation+mb_Ok);
Halt;
end;
Меня эта штука ещё не поводила! Этот кусок кода нужно класть в самый dpr - файл перед операторомApplication.Initialize
← →
VuDZ (2002-02-07 12:37) [21]кхм...
а как такое:
в каталоге конфигурации программы или в temp"e создаём файл типа mycoolsoft.log в котором будет прописан pid первого экземпляра программы
при запуске проверяем наличие такого файла, если есть - ищем такой процесс. если его нет, то программу вырубили экстренно, очищаем файл, иначе передаём фокус на первый экземпляр приложения...
и делов-то, и работает со 100% гарантией, если есть голова
← →
Johnmen (2002-02-07 13:33) [22]>VuDZ © : К чему такие корявые сложности, если в Win есть спец.механизмы для решения проблемы (см.выше) ?
← →
VuDZ (2002-02-07 13:35) [23]незнаю зачем, но часть софта, которым я пользуюсь и который написан профессионалами так и делает - apache для примера. Это даёт 100% гарантию и можно отследить, успешно завершился софт или нет...
ЗЫ где тут сложности, я не вижу... дел - на 2 мин...
← →
ASGroup (2002-02-07 17:49) [24]Есть такая АПИ
← →
ASgroup (2002-02-07 17:51) [25]qwqwq
← →
Raptor (2002-02-07 22:43) [26]2 VuDZ
Этот метод годится только для того, что бы, как ты сказал, можно отследить, успешно завершился софт или нет.
А для того, что бы не допустить запуска двух екземпляров одного приложения не совсем подходит. У него те же недостатки, что и у способа с использованием FindWindow.
← →
VuDZ (2002-02-07 23:22) [27]why?
я использовал пару раз такой метод - и всё работало отлично. и обойти эту защиту никак нельзя... если правильно сделать
← →
Johnmen (2002-02-08 11:20) [28]>VuDZ © : С apache пример неудачный, т.к. он изначально не заточен под win платформу...
← →
VuDZ (2002-02-08 13:08) [29]но на мой взгляд, этот метод даёт 100% гарантию того, что не будет запущен второй экземпляр приложения.
← →
Koudrinski (2002-03-13 19:25) [30]Mutex"ы вещь хорошая, только под WinXP, если нужно блокировать любой повторный запуск приложения при сделанном Switch User, они не работают (сам проверял в связи с этой проблемой). В каждои сеансе Mutex"ы независимы.
Пока я остановился на варианте открыти определённого файла c доступом для записи. Соответственно, другое приложение этого сделать не может. Хотя, это, конечно, не решение. Но в моём случае этого хватает.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.05.16;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.006 c