12
votes

Comment exécuter une seule instance d'application

J'ai une application qui utilise une connexion de socket pour envoyer et recevoir des données d'une autre application. Lors de la création de socket, il utilise le port 4998.

C'est là que mon problème mentez. Une fois que je démarre mon application, la prise commence à l'aide du port 4998. Donc, si je souhaite exécuter l'application à nouveau, j'obtiens une erreur de reliure de socket.

Donc, je veux limiter mon instance d'application à une. Cela signifie que si l'application est déjà en cours d'exécution et que quelqu'un essaie d'exécuter à nouveau l'application en cliquant sur l'icône Exe ou raccourci, il ne faut pas exécuter le programme, il ne doit pas apporter l'application existante au sommet.


0 commentaires

6 Réponses :


5
votes

Créer un événement nommé au début et vérifiez le résultat. Application proche si l'événement existe déjà.

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;
}


1 commentaires

Si CreatEvent () échoue, vous ne pouvez pas dire si l'application est déjà en cours d'exécution ou non, vous devez donc sortir, ne pas continuer.



11
votes

Vous pouvez utiliser Named Mutex.

échantillon de code de la Article : xxx


4 commentaires

En appelant OpenMutex () d'abord, vous avez une condition de course. Call Createmutex / EX () d'abord. Il vous dira si le mutex existe déjà. Appelez OpenMutex () uniquement si Createmutex () échoue avec une erreur ERROR_Access_Dentied.


Des conseils sur la façon de faire de ce travail sur Win7 +? Les mutiles globaux \ x ne se voient pas de différentes séances d'ouverture de l'utilisateur ...


@ Romanplášil ils font réellement, vous devez avoir fait quelque chose de mal


SI (! Createmutex (NULL, VRAI, L "QUELA GUID") || GetLasterRor () == error_already_exists) Retour 1; suffit !?



0
votes

Vous n'avez pas déjà un moyen de vérifier si votre application est en cours d'exécution? Qui a besoin d'un mutex, si le port est déjà pris, vous savez que l'application est en cours d'exécution!


6 commentaires

Oui maintenant, je au lieu de montrer l'erreur que je dois apporter ma demande en utilisant l'ID de processus. De l'aide?


Juste parce que le port est utilisé, cela ne signifie pas que votre demande utilise.


@ JO, bonne prise. Le port peut être utilisé par une autre application


@OJ Qu'est-ce que vous avez l'intention de faire différemment si une autre application utilise le port?


Votre application ne s'exécute qu'une seule fois, vous avertiez l'utilisateur (mieux, dites à l'utilisateur que l'application utilise le port), donnez-leur la possibilité de fermer cette application afin que votre application puisse tenter de relier le port.


"Qu'est-ce que vous avez l'intention de faire différemment si une autre application utilise le port?" - Affichage d'une invite d'erreur différente serait un choix assez évident. "[I] F Le port est déjà pris, vous savez que l'application est en cours d'exécution!" - er, non. Vous savez que le port n'est pas disponible. Et c'est vraiment tout ce que vous savez. Sauter aux conclusions ne confondera que l'utilisateur lorsqu'un message d'erreur trompeur apparaît. J'ai peur, jetant la solution appropriée et proposer un système de coïncidence par coïncidence exige un vote. Désolé.



6
votes

/ * J'ai trouvé l'édition nécessaire à être fait. Ajouté du code et des modifications supplémentaires nécessaires. Le présent fonctionne parfaitement pour moi. Merci Kirill V. Lyadvinsky et Remy Lebeau pour l'aide !!

* / xxx

/ * Le code ci-dessus fonctionne même lorsque l'on essaie d'ouvrir une seconde instance à partir d'une connexion différente, laissant la première connexion ouverte avec son instance en cours d'exécution. * /


0 commentaires

9
votes

Lorsque votre application initiale, créez un mutex. Si cela existe déjà, trouvez la demande existante et apportez-la au premier plan. Si l'application dispose d'un titre fixe pour sa fenêtre principale, il est facile à trouver avec Findwindow code>.

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.
}


2 commentaires

Pourquoi non seulement utiliser Findwindow (), si le nom de la classe de fenêtre est unique?


@Lovelyhanibal Les deux cas pourraient procéder via leurs chèques FindWindow avant de créer sa fenêtre.



1
votes

Vous pouvez y parvenir dans votre fonction WindowLain en appelant la fonction Findwindow avec le nom de la classe et le titre de votre fenêtre principale au tout début. Si la fenêtre existe, vous pouvez indiquer un message à l'utilisateur ou simplement montrer la fenêtre, puis revenir: xxx


0 commentaires