Domanda

Ho un'applicazione senza finestre il cui unico scopo è quello di installare un file DLL gancio a 32 bit e attendere che il programma principale (un programma a 64 bit) uscite. Il programma a 64 bit è scritto in C #, e l'applicazione di finestre è scritto in C ++. Inizialmente avevo questo ciclo GetMessage che ha tenuto il programma aperto:

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

stavo chiudendo l'applicazione C ++ utilizzando il metodo Process.Kill in C #, ma ho scoperto che non sta permettendo l'applicazione C ++ per vicino in modo pulito. Inoltre, se l'applicazione C # è caduto, l'applicazione C ++ sarebbe rimasto aperto per sempre. Ho fatto il controllo di un'applicazione C ++ per vedere se l'applicazione C # è ancora in funzione, con questo ciclo:

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

    if(!isMainProgramRunning())
        break;

    Sleep(1000);
}

Per qualche motivo il sonno provoca problemi. I ganci installati dal file DLL sono WH_CBT e WH_KEYBOARD. Ogni volta che si preme un tasto mentre l'applicazione C ++ è in esecuzione con questo ciclo, i tasti appena mangiati in su. Rimozione del sonno lo fa funzionare bene, ma, come previsto, si utilizza il 100% CPU , che ho non vogliono. Ho provato a rimuovere il ciclo di messaggi del tutto e invece utilizzare WaitForSingleObject con un timeout infinito su un filo che finirebbe quando isMainProgramRunning restituito false. Ciò blocca in sostanza l'intero computer.

Io non capisco il motivo per cui GetMessage, che, per quanto ho visto, non è più tornato, ma ha sospeso il thread principale a tempo indeterminato, non ha causato questi problemi ancora WaitForSingleObject provoca ogni applicazione di congelare quando clicco su di esso. Come posso ottenere l'applicazione C ++ a rimanere aperti fino alla chiusura C # applicazione?

Modifica:

Dal momento che è stato mi ha fatto notare che dormire in una pompa di messaggio viene male, lascia che chieda questo: C'è un modo per specificare un timeout sul attesa messaggio, in modo che il programma non è in attesa a tempo indeterminato per un messaggio, ma piuttosto, si attendere circa 250 ms, timeout, mi permetta di eseguire il metodo isMainProgramRunning, quindi attendere ancora un po '?

Edit2:

Ho provato ad utilizzare MsgWaitForMultipleObjects, anche se in modo un po 'diverso rispetto Leo suggerito. Questo è il ciclo che ho usato:

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

    if(!isMainProgramRunning())
        break;
}

Ancora una volta ho avuto lo stesso problema con il sonno. Ho anche provato che sospende il filo principale e avente l'altra filo ripristinarla. Stesso problema. Che cosa è che GetMessage non che gli permette di aspettare senza causare questi problemi? Forse questo dovrebbe essere oggetto di un altro post, ma perché è che quando l'applicazione C ++ installazione dei posti letto ganci o viene sospesa, tutte le lavorazioni nei ganci sembra di sospendere così?

Edit3:

Ecco il metodo DLL che le chiamate di applicazione C ++ per installare i ganci:

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);
}
È stato utile?

Soluzione

GetMessage non ritorna mai è perché non si dispone di una finestra creata!

Per usare un messaggio coda si deve avere un po 'interfaccia grafica. È possibile ad esempio creare una finestra nascosta.

Altri suggerimenti

Hai due problemi distinti:

  1. Come rendere l'uscita programma di finestre C ++ automaticamente se il programma C # uscite (ad esempio crash).

    Nel programma C ++, aprire un handle per il programma C #. Dal momento che il programma C # esegue il programma C ++, avere il programma C # passare il proprio PID come argomento; il programma C ++ può quindi aprire una maniglia a tale processo utilizzando OpenProcess .

    Quindi utilizzare MsgWaitForMultipleObjects il vostro ciclo di messaggi. Se il programma C # esce il manico si deve ad esso viene segnalata e vi si sveglierà. (È inoltre possibile utilizzare WaitForSingleObject(hProcess,0)==WAIT_OBJECT_0 per verificare se il processo viene segnalata o meno, ad esempio, per verificare il motivo per cui si erano svegliati, anche se i MsgWaitForMultipleObjects risultato vi dirà che pure.)

    Si dovrebbe chiudere l'handle di processo, come si sta uscendo (anche se il sistema operativo lo farà per voi quando si esce, è buona pratica nel caso in cui si ri-utilizzare questo codice in un contesto diverso). Nota che la maniglia sopravvive al processo che rappresenta, ed è per questo che si può attendere su di esso.

  2. Come rendere il programma C # istruire il programma C ++ per uscire.

    Potrebbe non essere necessario questo se si ottiene 1 # di lavoro, ma si può solo avere il programma C # inviare un messaggio al C ++ uno se si desidera.

    Non utilizzare PostQuitMessage e non pubblicare o inviare WM_QUIT attraverso thread o processi.

    Invece, inviare qualche altro messaggio che le due applicazioni d'accordo su (ad esempio WM_APP + 1) con PostThreadMessage .

È possibile creare un evento denominato e l'uso:

MsgWaitForMultipleObjects

nel ciclo di messaggi.

L'applicazione # C hanno solo per aprire e sollevare questo evento per raccontare la vostra applicazione per uscire.

E 'una specie di comunicazione tra processi minimo.

Si deve uscire dal processo inviando un messaggio WM_QUIT ad esso e gestire in modo corretto, come specificato nel questo articolo (Modalità) , da Raymond Chen. Non dormire all'interno di un ciclo, senza la gestione dei messaggi - è sbagliato. La vostra applicazione dovrebbe essere o la manipolazione di un messaggio o in attesa di nuovi messaggi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top