Блокировка повторного запуска
Нашёл ряд способов блокировки повторного запуска программы.
Первый, примерно выглядит следующим образом:
if(!FileExists(FileBlockNm))
iFileHandle = FileCreate(FileBlockNm);
else
{
MessageBox(NULL,"Already exist!!!","Error",MB_OK + MB_ICONSTOP + MB_TOPMOST);
Application->Terminate();
}
Второй связан с мьютексами.
А существуют ли какие-либо стандартные, проверенные временем способы?
Просто стало интересно, есть ли ещё что-то общеупотребимое. Ну или как вариант какие-нибудь другие методики.
Проверить существование в системе процесса с таким же именем. Но это менее производительный метод чем мьютексы.
Способов еще много, например делать запись в реестре. Кстати можно использовать не только мьютексы, но и любой именованный объект ядра.
Надеюсь это не совет к практическому применению? :)
ИМХО реестр - это штука для системных значений, но никак не для приложений (я замучился его уже чистить от всякого софта)
Согласен. Тоже не люблю этот способ :)
Привел просто как один из существующих вариантов.
Заметил одну странность. Есть программа (обычное windows приложение), которая соответственно имеет GUI, она занимается опросом оборудования и заворачивает полученные данные в OPC-теги, (т.е. по сути OPC-сервер). Данные от неё получают OPC клиенты. Два раза один и тот же сервер запускать нельзя!!! (проверка и обработка этого была реализована через мьютексы). Но есть некоторые клиенты, которые запускают сервер в фоновом режиме (в Task Manager сервер есть, а его GUI не загружено) и почему-то в этом случае проверка на повторный запуск срабатывает только на второй раз :( .
Можно ли как-то обеспечить загрузку приложения полностью (т.е. вместе с GUI)?
P.S. Мьютекс обрабатывается в ::InitInstance()
ИМХО реестр - это штука для системных значений, но никак не для приложений (я замучился его уже чистить от всякого софта)
вобщето реестр - это системная база содержащая настройки, как системы так и приложений в том числе. Конечно через реестр отслеживать запуск одной копии - это бред, но в основном по причине того, что гарантировано обеспечить транзакционность в данном случае не возможно - да и чтение из реестра по скорости не ахти.
И менее надежный.
Напр. в начале программа загружается системой (от имени System), т.е. видим оболочку и можем с ней преспокойно работать, а потом её же запускает пользователь (от имени Administrator). В моём случае (обработка запуска идёт через мьютексы) запускаются две копии программы и приспокойно себе работают. (Правда очень даже неспокойно :( они обе начинают обращаться с одному и тому же оборудованию через COM порт :)))
Если приложение не является COM объектом и/или не является частью системы то в реестре ему делать нечего (кроме как зарегить свой тип расширений файлов). А для настроек приложения есть *.ini/cgf-файлы и иже с ними. Это ИМХО, почему, описал выше постом в скобочках.
Возможно. Хотя у многих авторов и, кстати, в MSDN утверждается, что ini-файлы устарели и приложения должны хранить свои настройки в реестре.
[QUOTE=MSDN;]
Note This function is provided only for compatibility with 16-bit Windows-based applications. Applications should store initialization information in the registry.
[/QUOTE]
Не утверждаю, конечно, что это истина в последней инстанции, просто привожу факты.
Ну его нафиг, xml погибче будет в любом случае.
Мелкософт вообще понять сложно... я где то слышал (вроде даже на этом форуме), что они хотят отказаться от реестра или запретить приложениям вносить туда свои коррективы.
Напр. в начале программа загружается системой (от имени System), т.е. видим оболочку и можем с ней преспокойно работать, а потом её же запускает пользователь (от имени Administrator). В моём случае (обработка запуска идёт через мьютексы) запускаются две копии программы и приспокойно себе работают. (Правда очень даже неспокойно :( они обе начинают обращаться с одному и тому же оборудованию через COM порт :)))
приведите свой код, в котором вы используете мьютекс.
2 oxotnik333 активно используете в своей работе ОДБС? :)
активно используете в своей работе ОДБС? :)
вообще не использую...
ADO и иногда IBase - компоненты (в билдере)
ADO и иногда IBase - компоненты (в билдере)
мда.
То о чем вы подумали - это Open DataBase Connectivity - АПИ к БД, который в том числе использует и ADO - у Мольера есть такой персонаж - он страшно удивился, узнав о том что говорит прозой.
А я имел ввиду - ОДна Бабка Сказала - у вас это помоему важнейший источник информации.
Мелкософт вообще понять сложно... я где то слышал (вроде даже на этом форуме), что они хотят отказаться от реестра или запретить приложениям вносить туда свои коррективы.
if(mx)
{
::MessageBox(NULL,"Another Instance of program already exists","Warning",MB_OK|MB_ICONWARNING);
WaitForSingleObject(mx,INFINITE);
CloseHandle(mx);
return 0;
}
else // mutex not found, create
{
mx=CreateMutex(NULL,TRUE,"SRV");
}
ну а потом соответственно в конце работы
CloseHandle(mx);
if(mx)
{
::MessageBox(NULL,"Another Instance of program already exists","Warning",MB_OK|MB_ICONWARNING);
WaitForSingleObject(mx,INFINITE);
CloseHandle(mx);
return 0;
}
else // mutex not found, create
{
mx=CreateMutex(NULL,TRUE,"SRV");
}
ну а потом соответственно в конце работы
CloseHandle(mx);
Ну а где проверка, что CreateMutex завершился успешно и почему, если неуспешно?
А еще лучше проверить сначала, почему мьютекс не открылся.
Именно из-за этого у тебя и проблемы.
if FindWindow('TForm1', 'Form1') <> 0 then
begin
ShowMessage('Экземпляр программы запущен!');
SetForegroundWindow(FindWindow('TForm1', 'Form1'))
end
else
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
{
HANDLE hMutex=CreateMutex(NULL,true,"MyUnicalMutex::)" );
if(GetLastError()==ERROR_ALREADY_EXISTS)exit(0);
.......
}