Как запустить только один экземпляр приложения
У меня есть приложение, которое использует соединение сокета для отправки и получения данных из другого приложения. При создании сокета он использует порт 4998.
Вот где моя проблема. Как только я запустил приложение, сокет начнет использовать порт 4998. Поэтому, если я хочу снова выполнить приложение, я получаю ошибку привязки сокета.
Итак, я хочу ограничить свой экземпляр приложения одним. Это означает, что если приложение уже запущено, а кто-то пытается снова запустить приложение, щелкнув значок exe или ярлык, он не должен запускать программу, вместо этого он должен принести существующее приложение в верхнюю часть.
Ответы
Ответ 1
Вы можете использовать named mutex.
Пример кода из article:
WINAPI WinMain(
HINSTANCE, HINSTANCE, LPSTR, int)
{
try {
// Try to open the mutex.
HANDLE hMutex = OpenMutex(
MUTEX_ALL_ACCESS, 0, "MyApp1.0");
if (!hMutex)
// Mutex doesn’t exist. This is
// the first instance so create
// the mutex.
hMutex =
CreateMutex(0, 0, "MyApp1.0");
else
// The mutex exists so this is the
// the second instance so return.
return 0;
Application->Initialize();
Application->CreateForm(
__classid(TForm1), &Form1);
Application->Run();
// The app is closing so release
// the mutex.
ReleaseMutex(hMutex);
}
catch (Exception &exception) {
Application->
ShowException(&exception);
}
return 0;
}
Ответ 2
/*
Я нашел необходимое редактирование. Добавлен дополнительный код и исправления, которые необходимы. Настоящий отлично работает для меня. Спасибо, Кирилл В. Лядвинский и Реми Лебо за помощь!
*/
bool CheckOneInstance()
{
HANDLE m_hStartEvent = CreateEventW( NULL, FALSE, FALSE, L"Global\\CSAPP" );
if(m_hStartEvent == NULL)
{
CloseHandle( m_hStartEvent );
return false;
}
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
CloseHandle( m_hStartEvent );
m_hStartEvent = NULL;
// already exist
// send message from here to existing copy of the application
return false;
}
// the only instance, start in a usual way
return true;
}
/*
Вышеприведенный код работает, даже когда вы пытаетесь открыть второй экземпляр ОТ РАЗЛИЧНОГО ВХОДА, ВЫХОДЯЩЕГО ПЕРВЫЙ ВХОД, ОТКРЫВЫЙ С ЕГО ИНСТРУКЦИЕЙ.
*/
Ответ 3
Создайте именованное событие в начале и проверьте результат. Закройте приложение, если событие уже существует.
BOOL CheckOneInstance()
{
m_hStartEvent = CreateEventW( NULL, TRUE, FALSE, L"EVENT_NAME_HERE" );
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
CloseHandle( m_hStartEvent );
m_hStartEvent = NULL;
// already exist
// send message from here to existing copy of the application
return FALSE;
}
// the only instance, start in a usual way
return TRUE;
}
Закройте m_hStartEvent
в приложении.
Ответ 4
У вас уже есть способ проверить, работает ли ваше приложение? Кому нужен Mutex, если порт уже сделан, вы знаете, что приложение работает!
Ответ 5
Когда ваше приложение инициализируется, создайте мьютекс. Если он уже существует, найдите существующее приложение и выведите его на передний план. Если приложение имеет фиксированное название для главного окна, его легко найти с помощью FindWindow
.
m_singleInstanceMutex = CreateMutex(NULL, TRUE, L"Some unique string for your app");
if (m_singleInstanceMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) {
HWND existingApp = FindWindow(0, L"Your app window title");
if (existingApp) SetForegroundWindow(existingApp);
return FALSE; // Exit the app. For MFC, return false from InitInstance.
}