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

Вниз

Избежать двойной запуск программы.   Найти похожие ветки 

 
andrey__   (2004-10-05 16:21) [0]

Подскажите как осуществить следующее: Допустьм программа уже запущена и работает, но пользователь по какойто причине запускает повторно эту же программу. Мне надо чтобы второй экземпляр программы не запустился , а допустим показалася (активизировалася)интерфейс первой программы. Т.е. как мне кажется должна быть какая-то проверка при запуске программы на её повторный запуск. Как это сделать.


 
Amoeba ©   (2004-10-05 16:24) [1]

Смотри в FAQ!


 
Алхимик ©   (2004-10-05 16:25) [2]

Поспрошай Яндекс по ключевым словам "вторая копия".
Кучу вариантов предложит.


 
Jay   (2004-10-05 16:28) [3]

uses SyncObjs;
var check_event: TEvent;

check_event := TEvent.Create(nil, false, true, "MYPROGRAM_CHECKEXIST");
if check_event.WaitFor(10) = wrSignaled then
begin
...
end


 
Amoeba ©   (2004-10-05 16:30) [4]

Для этого в ряде библиотек (к примеру ABF) есть даже компоненты.


 
Amoeba ©   (2004-10-05 16:32) [5]

Здесь на сайте есть целая статья:
http://www.delphimaster.ru/articles/limit.html


 
XProger ©   (2004-10-05 22:37) [6]


hWnd := FindWindow("TForm", nil);
if hWnd <> 0 then
begin
if IsIconic(hWnd) then
 ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
Halt;
end;


 
Ihor Osov'yak ©   (2004-10-05 23:50) [7]

2 [6] XProger ©   (05.10.04 22:37)

Не делай так.
Как нужно - уже говорили. см. [5] Amoeba ©   (05.10.04 16:32).

В дополненее к статье упомяну, что нужно иметь ввиду, что на системе может быть несколько сессих (XP, терминальные сессии на сервере), посему нужно определить, где нужно "единственность" - на уровне сессии, или  на уровне системы.  Если сессии - это получается по умолчанию. если системы - перед именем именованного обьекта нужно указать  префикс "Global\"


 
tesseract   (2004-10-06 09:41) [8]

Пример класса Мютекса



// Сам класс
TMutex = class
 protected
   FHandle:Thandle;
 public
   function Acquire(Name: PChar):boolean;
   function Release: Boolean;
   function Get(TimeOut: Integer): Boolean;
 published
   destructor Destroy; override;
   constructor Create;
 end;
constructor TMutex.Create;
begin
 inherited Create;
end;

function TMutex.Acquire(Name: PChar):boolean;
begin
 FHandle := CreateMutex(nil, false, Name);
   if (FHandle = 0) or (FHandle=INVALID_HANDLE_VALUE) then    result:=false else result:=true;
// Если Мютекс один нужен просто говорим что нельзя если хочешь потоки синхронизировать то RTFM
   if GetLastError=ERROR_ALREADY_EXISTS then result:=false;
end;
// Ожидание освобождения - можешь выбросить
function TMutex.Get(TimeOut: Integer): Boolean;
begin
  if Fhandle<>0 then
    Result := WaitForSingleObject(FHandle, TimeOut) = WAIT_OBJECT_0
    else
    result:=true;
end;
// Закрываем мютекс
function TMutex.Release: Boolean;
begin
 Result := ReleaseMutex(FHandle);
end;
destructor Tmutex.Destroy;
begin
 if FHandle<>0 then Release;
 inherited Destroy;
end;


 А теперь как юзать, из реально работающего проекта


 program cool_server;

uses
 Windows,
 SysUtils,
 forms,
 Classes,
 uThread in "uThread.pas",
 Shared in "Shared.pas",
 formdll in "formdll.pas",
 Scale_frame in "Scale_frame.pas" {frScale: TFrame},
 settings in "settings.pas" {fmSettings};

{$R *.res}
var
fmWEight:TfmWeight;
AppMutex:Tmutex;
begin
 
If not AppMutex.Acquire("sserver") then exit;
   ScaleIniFile:=ExtractFilePath(application.ExeName)+"settings.ini";
 SetIniFile:=ExtractFilePath(application.ExeName)+"scale.ini";
 InitSettings(SetIniFile);
 ReadIni(ScaleIniFile);
 Addlog("Starting application");
 Application.Initialize;
 Application.CreateForm(TfmWeight, fmWeight);
 Application.CreateForm(TfmSettings, fmSettings);
 application.Run;
 AppMutex.release;
end.


 
OSokin ©   (2004-10-06 18:55) [9]

Атомами можно попробовать.
if
GlobalFindAtom("ATOM_FOR_ONCE_COPY_NAME") = 0 then
atom := GlobalAddAtom("ATOM_FOR_ONCE_COPY_NAME")
else сlose;


 
Ihor Osov'yak ©   (2004-10-07 02:18) [10]

2 [9] OSokin ©   (06.10.04 18:55)

Атомы плохо. Почему плохо - вскользь упрминается в сылке постинга [5].

2 [8] tesseract   (06.10.04 09:41)

Я вот не понимаю, зачем городить класс, где можно обойтись двумя-тремя апишными вызовами, максимум в пять строчек.

program BlaBla;

uses
 windows,
 ...
{$R *.RES}

var hSemaphore:THandle;

begin
 hSemaphore := CreateSemaphore(nil,0,1,"A4EFEC39-D9A3-4F45-A0C5-4B60D811E1EA");
 // сигнатура семафора - некий GUID, сгенерированный для даного проекта

 try
  if GetLastError = ERROR_ALREADY_EXISTS then begin
   // инстанция уже запущена,
   
   // здесь обычно код по переводу  уже запущеного приложения на передний план
   Exit;
  end;

  Application.Initialize;
 
  Application.CreateForm(...);
  Application.Run;

 finally
   ReleaseSemaphore(hSemaphore,0,nil);
 end;

end.


 
Ihor Osov'yak ©   (2004-10-07 02:21) [11]

некий GUID -> текстовое представление некоторого GUID


 
GanibalLector ©   (2004-10-07 02:39) [12]

2 Ihor Osov"yak © [10]
М-да...красиво.Взял на вооружение


 
tesseract   (2004-10-08 10:15) [13]

Ну если ты в одном месте проги используешь то да. А если используешт для синхронизации работы потоков, то лучше классами, оишбок мешьше, тем более и код лучше читаеться и в других проектах используеться.


 
Ihor Osov'yak ©   (2004-10-08 13:05) [14]

2 [13] tesseract   (08.10.04 10:15)

я "в одном месте проги" не использую. А вот кодированием и проектированием порою приходится заниматься. В том числе и многопоточных приложений. И ни разу не встречал ситуации, когда бы было целесообразным  строить классовый нахлабушник над обьектами синхронизаци типа семафоров.

Относительно читабельности. Гораздо проще узнать и сообразить что делает вызов типа CreateSemaphore, WaitForXXX, чем TMySuperPuperSinchroClass by Vasia Pupkin.. Особенно, если методы этого TMySuperPuperSinchroClass по сути есть вызов одной апишной функции.   И не следует забывть, что эти WaitForXXX очень подробно документрированы, чего не скажесь об очередном  TMySuperPuper...



Страницы: 1 вся ветка

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

Наверх




Память: 0.5 MB
Время: 0.05 c
4-1097348954
Sphinx
2004-10-09 23:09
2004.11.21
Таймер


4-1097258912
Дубинин Алексей
2004-10-08 22:08
2004.11.21
Поиск всех каталогов по выбранной маске, Рекурсия.


3-1098273092
Dysan
2004-10-20 15:51
2004.11.21
SQL запрос Group by по полю типа memo


4-1097143732
mtihonov
2004-10-07 14:08
2004.11.21
Переключение окон


14-1097151015
Красная Майка
2004-10-07 16:10
2004.11.21
MMP - Липки 2004