2017-06-26 8 views
-2

J'essaye de coder un petit "virus" (juste un programme de blague amusant qui dérange le curseur et émet des bips sonores). Cependant, je veux fermer ce processus avec ma clé F9.C++ fermer mon processus via la touche de raccourci

Voici ce que j'ai jusqu'à présent:

void executeApp() 
{ 
    while (true) 
    { 
     if (GetAsyncKeyState(VK_F9) & 0x8000) 
     { 
      exit(0); 
     } 
     Sleep(200); 
    } 
} 

J'ai fait un fil qui fonctionne cette fonction. Cependant, lorsque je cours mon code entier et que j'appuie sur F9, le processus s'exécute toujours. Seulement quand je l'appuie 2-3 fois, il arrive avec une erreur: "Debug Error! Abort() a été appelé."

Ce serait bien si quelqu'un sait comment je peux tuer mon processus via un raccourci clavier.

est ici tout le code du programme:

#include <iostream> 
#include <stdio.h> 
#include <windows.h> 
#include <conio.h> 
#include <ctime> 
#include <thread> 
#include <random> 

using namespace std; 

//random number gen for while loops in cursor/beep functions. 
random_device rd; 
mt19937 eng(rd()); 
uniform_int_distribution<> distr(1, 100); 

//variables used for this program. 
int random, Dur, X, Y, Freq; 
HWND mywindow, Steam, CMD, TaskMngr; 
char Notepad[MAX_PATH] = "notepad.exe"; 
char Website[MAX_PATH] = "http:\\www.google.de"; 

//functions 
void RandomCursor(), Beeper(), OpenStuff(), executeApp(); 

//threads 
thread cursor(RandomCursor); 
thread beeps(Beeper); 
thread openstuff(OpenStuff); 
thread appexecute(executeApp); 

int main() 
{ 
    srand(time(0)); 
    random = rand() % 3; 
    system("title 1337app"); 

    cursor.join(); 
    beeps.join(); 
    appexecute.join(); 

    return 0; 
} 

//void SetUp() 
//{ 
// mywindow = FindWindow(NULL, "1337app"); 
// cout << "oh whats that? let me see.\n"; 
// Sleep(1000); 
// ShowWindow(mywindow, false); 
//} 

void Beeper() 
{ 
    while (true) 
    { 
     if (distr(eng) > 75) 
     { 
      Dur = rand() % 206; 
      Freq = rand() % 2124; 
      Beep(Dur, Freq); 
     } 
     Sleep(1500); 
    } 
} 

//void OpenStuff() 
//{ 
// ShellExecute(NULL, "open", Notepad, NULL, NULL, SW_MAXIMIZE); 
// ShellExecute(NULL, "open", Website, NULL, NULL, SW_MAXIMIZE); 
//} 

void RandomCursor() 
{ 
    while (true) 
    { 
     if (distr(eng) < 50) 
     { 
      X = rand() % 302; 
      Y = rand() % 202; 
      SetCursorPos(X, Y); 
     } 
     Sleep(500); 
    } 
} 

void executeApp() 
{ 
    while (true) 
    { 
     if (GetAsyncKeyState(VK_F9) & 0x8000) 
     { 
      exit(0); 
     } 
     Sleep(200); 
    } 
} 
+2

Bienvenue sur Stack Overflow. Veuillez prendre le temps de lire [The Tour] (http://stackoverflow.com/tour) et de consulter le contenu du [Centre d'aide] (http://stackoverflow.com/help/asking) quoi et comment vous pouvez demandez ici. –

+1

La plupart du temps, vous appuyez sur la touche lorsque votre processus est endormi. Vous devriez étudier le traitement des messages Windows. –

+0

Vous devriez vérifier le comportement de votre thread pour voir ce qui se passe. Comme l'a dit @NeilButterworth, le fil pourrait être endormi la plupart du temps. En fonction de ce que vous avez ajouté, il se peut qu'il effectue une autre tâche et ne puisse pas traiter votre entrée à ce moment-là, provoquant une erreur comme celle que vous avez constatée. Ou vous pourriez avoir fait une erreur dans la création de fil. – Javia1492

Répondre

4

GetAsyncKeyState() renvoie deux éléments d'information, mais vous cherchez à un seul d'entre eux et il est celui qui est pas très utile à votre code.

par le documentation:

If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.

Lorsque vous AND la valeur de retour avec 0x8000, vous testez seulement le bit le plus significatif, ce qui signifie que vous testez que si la clé est actuellement vers le bas au l'instant exact est appelé GetAsyncKeyState(). C'est pourquoi il faut généralement plusieurs pressions, ou maintenir la touche enfoncée pendant un certain temps, pour que votre code détecte la pression sur la touche. Vous avez une condition de concurrence dans votre code.

Vous devez également AND la valeur de retour avec 0x0001 pour vérifier si la touche a été enfoncée et relâchée entre les temps que vous appelez GetAsyncKeyState():

if (GetAsyncKeyState(VK_F9) & 0x8001) 

Ou simplement:

if (GetAsyncKeyState(VK_F9) != 0) 

Ce étant dit, ce que vous devriez vraiment faire à la place est de surveiller le clavier et de le laisser vous dire quand vous appuyez sur la touche. Soit:


Mise à jour: Étant donné que votre code ne dispose pas d'un HWND propre, essayer SetWindowsHookEx(), par exemple:

#include <iostream> 
#include <stdio.h> 
#include <windows.h> 
#include <conio.h> 
#include <ctime> 
#include <thread> 
#include <random> 

using namespace std; 

//random number gen for while loops in cursor/beep functions. 
random_device rd; 
mt19937 eng(rd()); 
uniform_int_distribution<> distr(1, 100); 

//variables used for this program. 
int random, Dur, X, Y, Freq; 
HWND mywindow, Steam, CMD, TaskMngr; 
char Notepad[MAX_PATH] = "notepad.exe"; 
char Website[MAX_PATH] = "http://www.google.de"; 
HANDLE hExitApp = NULL; 

//functions 

//void SetUp() 
//{ 
// mywindow = FindWindow(NULL, "1337app"); 
// cout << "oh whats that? let me see.\n"; 
// Sleep(1000); 
// ShowWindow(mywindow, false); 
//} 

void Beeper() 
{ 
    if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT) 
    { 
     do 
     { 
      if (distr(eng) > 75) 
      { 
       Dur = rand() % 206; 
       Freq = rand() % 2124; 
       Beep(Dur, Freq); 
      } 
     } 
     while (WaitForSingleObject(hExitApp, 1500) == WAIT_TIMEOUT); 
    } 
} 

//void OpenStuff() 
//{ 
// ShellExecute(NULL, NULL, Notepad, NULL, NULL, SW_MAXIMIZE); 
// ShellExecute(NULL, NULL, Website, NULL, NULL, SW_MAXIMIZE); 
//} 

void RandomCursor() 
{ 
    if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT) 
    { 
     do 
     { 
      if (distr(eng) < 50) 
      { 
       X = rand() % 302; 
       Y = rand() % 202; 
       SetCursorPos(X, Y); 
      } 
     } 
     while (WaitForSingleObject(hExitApp, 500) == WAIT_TIMEOUT); 
    } 
} 

LRESULT CALLBACK MyLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    if (nCode == HC_ACTION) 
    { 
     switch (wParam) 
     { 
      case WM_KEYDOWN: 
      case WM_KEYUP: 
       if (reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->vkCode == VK_F9) 
        SetEvent(hExitApp); 
       break; 
     } 
    } 
    return CallNextHookEx(0, nCode, wParam, lParam); 
} 

void executeApp() 
{ 
    PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); 

    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &MyLowLevelKeyboardProc, NULL, 0); 
    if (hook) 
    { 
     MSG msg; 

     do 
     { 
      if (MsgWaitForMultipleObjects(1, &hExitApp, FALSE, INFINITE, QS_ALLINPUT) != (WAIT_OBJECT_0+1)) 
       break; 

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

     UnhookWindowsHookEx(hook); 
    } 

    SetEvent(hExitApp); 
} 

int main() 
{ 
    hExitApp = CreateEvent(NULL, TRUE, FALSE, NULL); 
    if (!hExitApp) return -1; 

    srand(time(0)); 
    random = rand() % 3; 
    system("title 1337app"); 

    //threads 
    thread cursor(RandomCursor); 
    thread beeps(Beeper); 
    thread openstuff(OpenStuff); 
    thread appexecute(executeApp); 

    cursor.join(); 
    beeps.join(); 
    openstuff.join(); 
    appexecute.join(); 

    CloseHandle(hExitApp); 
    return 0; 
} 
+0

pourriez-vous faire un exemple avec" SetWindowsHookEx() "pls? Je ne sais pas exactement quoi faire avec cette fonction, où l'implémenter et comment l'utiliser. Désolé si im agissant stupide à vous, mais je suis relativement nouveau à C++:/ – krobeN

+0

@krobeN: Réponse mis à jour –

+0

merci beaucoup! ça a vraiment beaucoup aidé;) – krobeN