Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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]

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

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

Форум: "WinAPI";
Текущий архив: 2002.05.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.006 c
14-50111
Rammish
2002-04-01 15:13
2002.05.16
О программизме, программации и программоделании


1-49908
_aero_
2002-05-02 15:51
2002.05.16
MeasureItem


14-50133
VictorT
2002-04-08 19:50
2002.05.16
Карпаты-Львов - Динамо-Киев


4-50165
ebeden
2002-03-15 03:12
2002.05.16
Internet Explorer


3-49865
mik
2002-04-19 15:01
2002.05.16
Странные дела!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский