C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Запрет запуска второй копии программы
LordConst
Отправлено: 09.02.2007, 11:29


Ученик-кочегар

Группа: Участник
Сообщений: 10



Вот задумался как это сделать что то ничего на ум не приходить... wink.gif
может кто то уже делал подскажет как или хотя бы с чего начать...
bred
Отправлено: 09.02.2007, 12:12


Ученик-кочегар

Группа: Участник
Сообщений: 15



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

вот еще примерчик под рукой нашелся:
CODE

char tempFile[MAX_PATH+1];
 if (GetTempPath(MAX_PATH, tempFile))
 {
   if (tempFile[lstrlen(tempFile)]=='\\')
     lstrcat(tempFile, "MayaProgramma.already.started");
   else
     lstrcat(tempFile, "\\MayaProgramma.already.started");

   HANDLE hFile = CreateFile(tempFile, GENERIC_WRITE, 0,
       NULL, CREATE_ALWAYS,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
       NULL);

   if(hFile == INVALID_HANDLE_VALUE)
   {
       ::MessageBox(NULL, "Невозможно запустить вторую копию программы", "Внимание", MB_OK|MB_ICONEXCLAMATION);
      return 1;
   }
 }


Отредактировано bred — 09.02.2007, 12:15
Valdemar
Отправлено: 09.02.2007, 14:59


Мастер участка

Группа: Участник
Сообщений: 433



Еще вариант. В программе сделать новый раздел с атрибутом SHARED, в который поместить переменную для подсчета запущенных экземпляров приложения. А при запуске проверять значение этой переменной и делать выводы.
CODE
// указываем компилятору поместить инициализированную переменную
// в раздел Shared, чтобы она стала диступной всем экземплярам программы

#pragma data_seg("Shared")
volatile LONG g_lApplicationInstances = 0;
#pragma data_seg()

// указываем компоновщику, что раздел Shared должен быть
// читаемым, записываемым и разделяемым
#pragma comment(linker, "/Section.Shared,RWS")
nawok78
Отправлено: 09.02.2007, 15:19


Станционный диспетчер

Группа: Участник
Сообщений: 115



делать не делал но по моему нужно поискать — зпущен или нет — а дальше делай что хочешь.

Отредактировано nawok78 — 09.02.2007, 15:21
AVC
Отправлено: 09.02.2007, 15:31


Ветеран

Группа: Модератор
Сообщений: 1583



Одна копия програмы, как реализовать?

Можно было и поискать.
LordConst
Отправлено: 12.02.2007, 11:44


Ученик-кочегар

Группа: Участник
Сообщений: 10



Прощу прощения плохо искал sad.gif
ion
Отправлено: 13.02.2007, 14:49


Ученик-кочегар

Группа: Участник
Сообщений: 15



Мало кто знает, но запрет можно осущесвить, при помощи атомов,
заносим при окрытии программы в атом значение, если он был пустой,
при открытии второго экземпляра проверяем, если атом пустой, — я первая
если атом занят, — абортируюсь smile.gif)
enton
Отправлено: 14.02.2007, 15:42


Дежурный стрелочник

Группа: Участник
Сообщений: 44



попробовал первый пример ругается на return в чем дело?
nawok78
Отправлено: 14.02.2007, 15:46


Станционный диспетчер

Группа: Участник
Сообщений: 115



если функция типа void то
CODE

return;

если функция типа int то возможно не хватает
CODE

return 0;


ну все как обычно smile.gif
enton
Отправлено: 14.02.2007, 16:37


Дежурный стрелочник

Группа: Участник
Сообщений: 44



бу-га-га...

пробовал....

окошко предупреждения выдается а прога все равно запускается!
bred
Отправлено: 16.02.2007, 01:55


Ученик-кочегар

Группа: Участник
Сообщений: 15



QUOTE (enton @ 14.02.2007, 16:37)
пробовал....

окошко предупреждения выдается а прога все равно запускается!

Если это относится к моему примеру, то вопрос: в куда его вставляли? В оригинале он вставлялся в project.cpp т.е. являлся частью процедуры WinMain.
enton
Отправлено: 26.02.2007, 09:36


Дежурный стрелочник

Группа: Участник
Сообщений: 44



нашел другой пример того же случая

CODE

const char *NamedMutex = "OneOnly";
HANDLE CheckInstance(const char *Name)
{
       HANDLE Mutex = CreateMutex(NULL,true, Name);
       int er= GetLastError();
       if (er) return 0;
       return Mutex;
}


...

HANDLE Mutex= CheckInstance(NamedMutex);
       if (!Mutex)
       {
               ShowMessage("Запуск второй копии программы запрещен");
               ReleaseMutex(Mutex);
               return 1;
       }


проверено код рабочий, использовал именно его.
Valery52
Отправлено: 26.02.2007, 14:02


Ученик-кочегар

Группа: Участник
Сообщений: 8



Еще один пример с применением мутексов.
Содержится только в .h файле:

CODE

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = CreateMutex(NULL,true,"DSP1_unique_mutex_Press2");
if (GetLastError()==ERROR_ALREADY_EXISTS)
       {
       // мы уже есть — ругаемся и выходим
ShowMessage(
"               СМОТРИ ВНИМАТЕЛЬНЕЕ!!! \n Программа уже запущена и лежит на панели задач!");
       Application->Terminate();
       } else
       {


     try
       {
                Application->Initialize();
                Application->Title = "Press2";
                Application->HelpFile = "";
                Application->CreateForm(__classid(Tmain_Form), &main_Form);
                Application->Run();
       }
       catch (Exception &exception)
       {
                Application->ShowException(&exception);
       }
       catch (...)
       {
                try
                {
                        throw Exception("");
                }
                catch (Exception &exception)
                {
                        Application->ShowException(&exception);
                }
       }


       ReleaseMutex(hMutex); // это обязательно, а то до
                             // перезагрузки прога второй раз не запустится
       }
       return 0;
}

DSP1_unique_mutex_Press2 — имя мутекса, включаю имя проги Press2.
Valery52
Отправлено: 27.02.2007, 08:53


Ученик-кочегар

Группа: Участник
Сообщений: 8



Прошу прощения, это должно быть в файле Project1.cpp, а не в .H

Вернуться в Вопросы программирования в C++Builder