Question

J'ai une application sans fenêtre dont le seul but est d'installer un fichier DLL crochet 32 ??bits et attendez que le programme parent (un programme 64 bits) sorties. Le programme 64 bits est écrit en C #, et l'application est sans fenêtre écrit en C ++. J'avais initialement cette boucle GetMessage qui a tenu ouvert le programme:

while(GetMessage(&msg, NULL, 0, 0) > 0)
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

Je fermais l'application C ++ en utilisant la méthode Process.Kill en C #, mais je trouve que ce ne permet pas l'application C ++ à proximité proprement. En outre, si l'application C # est écrasé, l'application C ++ resterait ouverte pour toujours. J'ai fait la vérification de l'application C ++ pour voir si l'application C # est toujours en cours, en utilisant cette boucle:

while(true)
{
    if(PeekMessage(&msg, NULL, 0, 0, true))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if(!isMainProgramRunning())
        break;

    Sleep(1000);
}

Pour une raison quelconque le sommeil provoque des problèmes. Les crochets installés par le fichier DLL sont WH_CBT et WH_KEYBOARD. Chaque fois que j'appuie sur une touche lorsque l'application C fonctionne de cette boucle, les touches Parvenez mangées. Retrait du sommeil fait fonctionner très bien, mais, comme prévu, il utilise 100% CPU , que je ne veulent pas. J'ai essayé de retirer la boucle de message tout à fait et au lieu d'utiliser WaitForSingleObject avec un délai d'attente infini sur un fil qui se terminerait quand isMainProgramRunning retourne faux. Cela verrouille essentiellement en tout l'ordinateur.

Je ne comprends pas vraiment pourquoi GetMessage, qui, pour autant que je scie, ne revint jamais, mais a suspendu le fil conducteur indéfiniment, n'a pas encore la cause de ces problèmes WaitForSingleObject provoque toutes les applications de geler quand je clique dessus. Comment puis-je obtenir l'application C ++ pour rester ouvert jusqu'à ce que l'application C # ferme?

Edit:

Comme il a été souligné pour moi que dormir dans une pompe de message est une mauvaise chose, laissez-moi poser cette question: Y at-il un moyen de spécifier un délai d'attente sur l'attente de messages, de sorte que le programme n'attend pas indéfiniment un message, mais plutôt, va attendre environ 250 ms, délai d'attente, laissez-moi exécuter la méthode isMainProgramRunning, puis attendre encore un peu?

Edit2:

J'ai essayé d'utiliser MsgWaitForMultipleObjects, bien que d'une manière quelque peu différente de Leo suggéré. Ceci est la boucle je:

while(MsgWaitForMultipleObjects (0, NULL, true, 250, QS_ALLPOSTMESSAGE) != WAIT_FAILED)
{
    if(PeekMessage(&msg, NULL, 0, 0, true))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if(!isMainProgramRunning())
        break;
}

Encore une fois, j'ai eu le même problème avec le sommeil. J'ai aussi essayé de suspendre le fil principal et ayant l'autre thread le reprendre. Même problème. Qu'est-ce que GetMessage ne qui lui permet d'attendre sans causer ces problèmes? Peut-être que cela devrait faire l'objet d'un autre poste, mais pourquoi est-ce que lorsque l'application C ++ l'installation des crochets dorme ou qu'il est suspendu, tout le traitement dans les crochets semble suspendre aussi bien?

Edit3:

Voici la méthode DLL C ++ que les appels d'application pour installer les crochets:

extern "C" __declspec(dllexport) void install()
{
    cbtHook = SetWindowsHookEx(WH_CBT, hookWindowEvents, hinst, NULL);

    if(cbtHook == NULL)
        MessageBox(NULL, "Unable to install CBT hook", "Error!", MB_OK);

    keyHook = SetWindowsHookEx(WH_KEYBOARD, LowLevelKeyboardProc, hinst, NULL);

    if(keyHook == NULL)
        MessageBox(NULL, "Unable to install key hook", "Error!", MB_OK);
}
Était-ce utile?

La solution

GetMessage ne retourne jamais parce que vous n'avez pas une fenêtre créée!

Pour utiliser un message-file d'attente, vous devez avoir une interface graphique. Vous pouvez par exemple créer une fenêtre cachée.

Autres conseils

Vous avez deux problèmes distincts:

  1. Comment faire la sortie du programme sans fenêtre C ++ automatiquement si les sorties du programme C # (par exemple plante).

    Dans le programme C ++, ouvrez une poignée au programme C #. Depuis que le programme C # exécute le programme C ++, que le programme C # passe son propre PID comme argument; le programme C ++ peut ensuite ouvrir une poignée à l'aide de ce processus OpenProcess .

    Ensuite, utilisez MsgWaitForMultipleObjects votre boucle de message. Si le programme C # sort de la poignée, vous devez, il sera signalé et vous réveiller. (Vous pouvez également utiliser WaitForSingleObject(hProcess,0)==WAIT_OBJECT_0 pour vérifier si le processus est signalé ou non, par exemple pour vérifier pourquoi vous avez été réveillé, bien que les MsgWaitForMultipleObjects résultat vous dira aussi.)

    Vous devez fermer la poignée de processus que vous quittez (même si le système d'exploitation le fera pour vous lorsque vous quittez, il est une bonne pratique dans le cas où vous réutiliser ce code dans un autre contexte). Notez que la poignée du processus qu'il survive représente, et qui est la raison pour laquelle vous pouvez attendre sur elle.

  2. Comment rendre le programme C # indiquer au programme C ++ pour quitter.

    Vous ne pouvez pas besoin si vous obtenez # 1 travail, mais vous pourriez avoir le programme C # envoyer un message à la C ++ un si vous voulez.

    Ne pas utiliser PostQuitMessage et ne pas afficher ou envoyer WM_QUIT dans les threads ou processus.

    Au lieu de cela, afficher un autre message les deux applications sont d'accord sur (par exemple WM_APP + 1) en utilisant PostThreadMessage .

Vous pouvez créer un événement nommé et l'utilisation:

  

MsgWaitForMultipleObjects

dans votre boucle de message.

L'application C # suffit d'ouvrir et d'élever cet événement pour dire à votre application à la sortie.

Il est une sorte de communication entre un minimum.

Vous devriez quitter le processus en affichant un message WM_QUIT à et manipuler correctement, comme spécifié dans cet article (Modality) , par Raymond Chen. Ne pas dormir dans une boucle sans gestion des messages - ce qui ne va pas. Votre application doit être soit la manipulation d'un message ou en attente de nouveaux messages.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top