Как проверить запущена ли программа?
Мне надо зделать так: если программа запужена, то не запускатся второй раз, как это зделать?
Кажись тут это уже раз сто обсуждалось.
Вобщем, можно через FindWindow-самый простой способ, можно через мутексы, семафоры, файлы в памяти. Выбирай на вкус:)
Kashuk
Не рекомендую использовать FindWindow, хотя многие говорят, что это проще. Эта функция не помогает в одном из распространенных случаев запуска второго экземпляра - лишнего клика мышкой по иконке. В это время окно первого экземпляра возможно еще не создано, поэтому результат FindWindow будет отрицательным и соответственно запустится второй экземпляр.
Более надежным является реализация через мьютекс.
{
CreateFile("c:\\AlreadyRun.tmp", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
}
else if (FileExists("c:\\AlreadyRun.tmp")==1)
{
MessageBox(0,"Program already run!\nPlz close the program and try again","",MB_ICONWARNING);
Application->Terminate();
}
самый простой и надежный способ!
-->снкс тому человеку,который его пне дал!
if (FileExists("c:\\AlreadyRun.tmp")!=1)
{
CreateFile("c:\\AlreadyRun.tmp", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
}
else if (FileExists("c:\\AlreadyRun.tmp")==1)
{
MessageBox(0,"Program already run!\nPlz close the program and try again","",MB_ICONWARNING);
Application->Terminate();
}
самый простой и надежный способ!
-->снкс тому человеку,который его пне дал!
Конечно, "на вкус и цвет товарищей нет", но этот способ ни в какие ворота не лезет. Если в способе с мьютексом есть один нюанс с высвобождением ресурса (мьютекса) при некорректном завершении программы, который лечиться (в крайнем случае) со стороны пользователя с помощью "Reset", то в случае с файлов этих нюансов пруд пруди. Первое что приходит в голову: что делать если программаа завершилась некорректно? Второй раз её, видимо, не запустить даже после перезагрузки. Да и не красиво как-то перед пользователем, открывает он свой диск С:, а там куча левых файлов, пациент в панике... А если диска С: в системе нет?
Я за мьютекс!
Если в способе с мьютексом есть один нюанс с высвобождением ресурса (мьютекса) при некорректном завершении программы, который лечиться (в крайнем случае) со стороны пользователя с помощью "Reset"
Никаких ньюансов с мьютексом нет. При любом завершении программы ОС обязана освободить все ресурсы приложения, в том числе и мьютексы.
Дырявая Win9x может иногда забыть об этом, но ее дни сочтены: все прогрессивное человечество переходит (или давным давно перешло, как я :cool: ) на NT !
P.S. Я тоже за мьютекс.
//---------------------------------------------------------------------------
void __fastcall TForm::FormCreate(TObject *Sender)
{
if (WeAreAlone ("MY_PROGRAMM.EXE"))
{
// Proceed
}
else
{
MessageBox (NULL,"Error","Ошибка: Программа уже загружена!",MB_OK|MB_ICONERROR);
exit(1);
}
}
//---------------------------------------------------------------------------
BOOL TClientForm::WeAreAlone (LPSTR szName)
{
HANDLE hMutex = CreateMutex (NULL, TRUE, szName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
Но проблема опять же кроется в мьютексах, если приложение будет некоректно завершено, то запустить второй раз приложение без перезагрузки компа ты не сможешь.
Сколько раз пытался, так и не удалось завершить приложение так некорректно, чтобы пришлось перезагрузаться. Открой секрет.
// Как проследить чтобы только одна копия приложения работала в данный момент
//---------------------------------------------------------------------------
void __fastcall TForm::FormCreate(TObject *Sender)
{
if (WeAreAlone ("MY_PROGRAMM.EXE"))
{
// Proceed
}
else
{
MessageBox (NULL,"Error","Ошибка: Программа уже загружена!",MB_OK|MB_ICONERROR);
exit(1);
}
}
//---------------------------------------------------------------------------
BOOL TClientForm::WeAreAlone (LPSTR szName)
{
HANDLE hMutex = CreateMutex (NULL, TRUE, szName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
Но проблема опять же кроется в мьютексах, если приложение будет некоректно завершено, то запустить второй раз приложение без перезагрузки компа ты не сможешь.
Большое спасибо за примерчик bercut, обязательно его испробую, а то что касается зависания, так то не столь важно, надобудет, то перезагрузятся!
Большое спасибо всем!!!
А как теперь при повторном запуске проекта зделать так, что б место вывода ошибки, превый запущеный(если был свёрнут, то востанавливался, как Winamp к примеру), подскажите что туна надо записать.
На берёд благодарю!
Помогите ещё раз!
А как теперь при повторном запуске проекта зделать так, что б место вывода ошибки, превый запущеный(если был свёрнут, то востанавливался, как Winamp к примеру), подскажите что туна надо записать.
HWND hWnd;
hWnd = FindWindow(AppName, NULL);
if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE);
Это уже делаешь после проверки существования мьютекса.
bercut
Сколько раз пытался, так и не удалось завершить приложение так некорректно, чтобы пришлось перезагрузаться. Открой секрет.
Ни каких секретов. У меня это получилось с первого раза, а ты значит плохо пытался. ;-)
А делается это таким образом, хотя не всегда срабатывает, просто прогу надо завершить не через Close(), а чтобы прога убила свой собсвенный процесс в памяти, после чего там оставался мьютекс и загрузить прогу второй раз уже не удавалось. Вот и все.
А делается это таким образом, хотя не всегда срабатывает, просто прогу надо завершить не через Close(), а чтобы прога убила свой собсвенный процесс в памяти, после чего там оставался мьютекс и загрузить прогу второй раз уже не удавалось. Вот и все.
Как убить процесс ? TerminateProcess ? Пробовал - работает как часы и под Win2k и под Win98. Исходник что ли пришли, а то долго еще трепаться будем :).
bercut
Как убить процесс ? TerminateProcess ? Пробовал - работает как часы и под Win2k и под Win98. Исходник что ли пришли, а то долго еще трепаться будем :).
Да, ты прав, убиваю процесс именно с помощью TerminateProcess, но т.к. прога убивает сама себя она заверщается не корректно. При этом она не выдает ни каких сообщений и закрывается, но если посмотреть список процессов в памяти, то видно, что она так в памяти и висит и при этом уже ничем не убивается. Исходник высылать не буду, т.к. он не для общего обозрения, а вот готовое приложение могу, которое весит около метра.
Да, ты прав, убиваю процесс именно с помощью TerminateProcess, но т.к. прога убивает сама себя она заверщается не корректно. При этом она не выдает ни каких сообщений и закрывается, но если посмотреть список процессов в памяти, то видно, что она так в памяти и висит и при этом уже ничем не убивается.
Как же ты убиваешь процесс, если он висит в памяти ? Что-то ты перемудрил с "убийством". :)
Если программа потом ничем не закрывается, смею предположить дело происходит под 9х, здесь такое бывает. Под NT TerminateProcess работает железно.
bercut писал ...
segev писал ...
Как же ты убиваешь процесс, если он висит в памяти ? Что-то ты перемудрил с "убийством". :)
Если программа потом ничем не закрывается, смею предположить дело происходит под 9х, здесь такое бывает. Под NT TerminateProcess работает железно.
твои б слова да богу в уши
я сам работаю на Win2k и примеров некорректного завершения здесь море
- прога успела вывалиться в режим отладки под системную привелегию и "отлаживается" положив на всех остальных (кстати недавно закрытая дыра в НТ)
- создание дочернего процесса и порождение в нем мьютекса и вызов метода onClose с Active = caFree из другого дочернего процесса (вот это полная лажа системы)
- иногда закрытие приложения во время работы с сокетом
и тд и тп
ЗЫ: покой нам только сниться, а пока глаз да глаз
я сам работаю на Win2k и примеров некорректного завершения здесь море...
При чем здесь какое-то некорректное завершение чего-то там ?
Речь идет о том, что TerminateProcess всегда выгружает приложение из памяти и закрывает его все дескрипторы объектов ядра (к которым относятся и мьютексы).
За много лет общения с NT-системами ни разу не видел, чтобы приложение нельзя было снять из диспетчера задач (там вызывается именно TerminateProcess).
прога успела вывалиться в режим отладки под системную привелегию и "отлаживается"
Как это понимать и что такое "системная привелегия" ?