Как запустить только один экземпляр приложения - PullRequest
12 голосов
/ 16 ноября 2010

У меня есть приложение, которое использует сокетное соединение для отправки и получения данных из другого приложения. При создании сокета используется порт 4998.

Вот в чем моя проблема. Как только я запускаю свое приложение, сокет начинает использовать порт 4998. Поэтому, если я хочу снова запустить приложение, я получаю ошибку привязки сокета.

Итак, я хочу ограничить свой экземпляр приложения одним. Это означает, что если приложение уже запущено и кто-то пытается запустить приложение снова, щелкнув значок exe или ярлык, оно не должно запускать программу, вместо этого оно должно вывести существующее приложение наверх.

Ответы [ 5 ]

12 голосов
/ 16 ноября 2010

Вы можете использовать именованный мьютекс.

Пример кода из статьи :

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;
}
5 голосов
/ 04 ноября 2015

Когда ваше приложение инициализируется, создайте мьютекс.Если оно уже существует, найдите существующее приложение и выведите его на передний план.Если приложение имеет фиксированный заголовок для основного окна, его легко найти с помощью 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's window title");
    if (existingApp) SetForegroundWindow(existingApp);
    return FALSE; // Exit the app. For MFC, return false from InitInstance.
}
5 голосов
/ 07 июня 2013

/ * Я нашел необходимое редактирование, чтобы сделать. Добавлен дополнительный код и необходимые изменения. Настоящий работает отлично для меня. Спасибо, Кирилл В. Лядвинский и Реми Лебо за помощь !!

* /

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 голосов
/ 16 ноября 2010

Создайте именованное событие на старте и проверьте результат. Закройте приложение, если событие уже существует.

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 при выходе из приложения.

0 голосов
/ 16 ноября 2010

У вас уже нет способа проверить, работает ли ваше приложение?Кому нужен Mutex, если порт уже занят, вы знаете, что приложение работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...