Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Избежать двойной запуск программы. [D6, Win2k]


andrey__ ©   (2004-10-05 16:21:00) 

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


Ihor Osov'yak   (2004-10-08 13:05:00) [1]

2 [13] tesseract   (08.10.04 10:15)

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

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


tesseract   (2004-10-08 10:15:00) [2]

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


GanibalLector   (2004-10-07 02:39:00) [3]

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


Ihor Osov'yak   (2004-10-07 02:21:00) [4]

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


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

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.


OSokin   (2004-10-06 18:55:00) [6]

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


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

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



// Сам класс
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.


Ihor Osov'yak   (2004-10-05 23:50:00) [8]

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

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

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


XProger   (2004-10-05 22:37:00) [9]


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


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

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


Amoeba   (2004-10-05 16:30:00) [11]

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


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

uses SyncObjs;
var check_event: TEvent;

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


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

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


Amoeba   (2004-10-05 16:24:00) [14]

Смотри в FAQ!


Наверх

Титульная страница Поиск, карта сайта Написать письмо