Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.05.16;
Скачать: CL | DM;

Вниз

Блокировка повторного запуска приложения   Найти похожие ветки 

 
NY152   (2002-01-29 14:03) [0]

Люди добрые, подскажите как проверить наличие копии программы в памяти чтобы исключить её повторный запуск ? В инете есть куски кода - но все они какие-то очень сложные, может кто пользуется чем-то уже давно, дайте процедурку =)
Заранее благодарен.
ПС: заранее прошу прощения, наверное уже были подобные вопросы, но я что-то не нашёл их, подскажите тогда ссылку =)


 
Бильврёст   (2002-01-29 14:21) [1]

Это очень просто реализуется с помощью мьютексов - посмотрите help - там всё очень доступно.


 
serg001   (2002-01-29 14:22) [2]

Вот главная прога:

program tvojaprogramma;

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 вся ветка

Текущий архив: 2002.05.16;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.014 c
14-50106
anod
2002-04-06 00:12
2002.05.16
Подскажите


4-50180
chernoruk
2002-03-16 22:20
2002.05.16
Вопрос: Get Process ID (path to a file.exe) ????????????


1-50004
Ronin
2002-04-30 02:08
2002.05.16
Как добавить ссылку на сайт в hlp файле?


1-49937
ko@ndrew
2002-05-03 22:11
2002.05.16
DirectPlay8


1-49913
snoup
2002-04-29 00:15
2002.05.16
Помогите пожалуйста, например я где-то в блокноте или в офисе пиш