Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Мьютексы


Автор: JS2 28.7.2010, 15:01
Нуждаюсь в вашем совете. Для консольного приложения нужно запретить возможность повторного запуска. Сделал так:

Код

program Updater;

{$APPTYPE CONSOLE}

uses
 Windows, SysUtils;
var
 Mutex: THandle;
begin
 Mutex := CreateMutex(nil, False, PChar(ExtractFileName(ParamStr(0))));
 try
   if GetLastError <> ERROR_ALREADY_EXISTS then
   begin
     // ...
   end;
 finally
   CloseHandle(Mutex);
 end;
end.


Нашел пример в котором указатель на имя mutex-object задан как: 'E191BA0C41924AA9840243D5CAE346AF'. 
- Будет ли более правильным такой подход?
- Нужно ли делать CloseHandle, если функция CreateMutex возвращает 0. Может правильнее try..finally блок перенести в if?

Автор: rytmix 28.7.2010, 19:38
Если хочешь на Mutex`ах смотри(там правда код на C, но почитать объяснения полезно):
http://forum.codenet.ru/archive/index.php/t-16028.html

Есть еще варианты, но там модули подключать придется(не мое, взял на http://www.sql.ru/forum/actualthread.aspx?bid=20&tid=189430&pg=2):

1) при запуске программа производит FindWindow(...), и если находит окно со своим названием, то дальше не инициализируется и закрывается.

2) при запуске производится CreateToolhelp32Snapshot(...) и Process32First(...)-Process32Next(...) в цикле, и если находим в памяти идентичный нашему szExeName, то выгружаемся. Если комбинировать оба способа, то выходит неплохо... Т.е. сочетание проверки по WindowCaption и ExeName позволяет нормально добиваться одиночества нашей программы.

Автор: ~FoX~ 28.7.2010, 20:15
Цитата(JS2 @  28.7.2010,  16:01 Найти цитируемый пост)
Нашел пример в котором указатель на имя mutex-object задан как: 'E191BA0C41924AA9840243D5CAE346AF'. 

Пофиг...нажми в редакторе кода Ctrl+Shoft+G получишь достаточно уникальный номер, его и вставляй...


Цитата(JS2 @  28.7.2010,  16:01 Найти цитируемый пост)
Нужно ли делать CloseHandle, если функция CreateMutex возвращает 0. Может правильнее try..finally блок перенести в if? 

Нет, не надо...Закроешь уже имеющийся мьютекс...

ИМХО так проще
Код

  hMutex := CreateMutex(nil, False, 'MyUniqueCoolMutex');
  if WaitForSingleObject(hMutex, 0) = wait_TimeOut then begin //если вышло время, значит объект уже существует...
        MessageBox(Application.Handle, PChar('Уже запущенно', PChar('Нифига'),  MB_ICONINFORMATION + MB_OK);
  end
  else begin
    //.......исполняем прогу....
  end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)