2017-06-26 127 views
-2

我試圖編寫一個小小的「病毒」(只是一個有趣的笑話程序,它隨着光標四處亂動,併發出一些嘟嘟聲)。但是,我想用我的F9鍵來關閉此過程。C++通過熱鍵關閉我的進程

這是我到目前爲止有:

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

我做了運行此功能的線程。但是,當我運行我的整個代碼並按F9時,該過程仍在運行。只有當我按下它2-3次時,纔會出現一個錯誤:「已調用調試錯誤!abort()」。

如果有人知道我可以通過熱鍵殺死我的進程,那將會很好。

下面是該程序的整個代碼:

#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

歡迎堆棧溢出。請花些時間閱讀[The Tour](http://stackoverflow.com/tour),並參閱[幫助中心](http://stackoverflow.com/help/asking)中的資料,瞭解您可以在這裏問。 –

+1

大多數情況下,當你的進程處於睡眠狀態時,你將會按下按鍵。您應該調查處理Windows消息。 –

+0

你應該檢查你的線程的行爲,看看發生了什麼。正如@NeilButterworth所說,線程可能在大多數時間都在睡覺。根據您添加的內容,它可能會執行一些其他任務,並且無法在導致您看到的錯誤時處理您的輸入。或者你可能在創建線程時犯了一個錯誤。 – Javia1492

回答

4

GetAsyncKeyState()回報的兩條信息,但你正在尋找只是其中之一,它是一個,是不是對你的代碼是非常有用的。

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.

當你AND0x8000返回值,如果正在測試只有最顯著位,這意味着你正在測試只有在關鍵的是目前下跌在確切時刻GetAsyncKeyState()被調用。這就是爲什麼它通常需要幾次按下,或者按住一段時間才能讓您的代碼檢測按鍵。你的代碼中有競爭條件。

您還AND應該檢查與0x0001返回值,如果鍵被按下,並您致電GetAsyncKeyState()的時間之間的發佈:

if (GetAsyncKeyState(VK_F9) & 0x8001) 

或者乾脆:

if (GetAsyncKeyState(VK_F9) != 0) 

那據說,你真正應該做的是實際監控鍵盤,讓它告訴你何時按下鍵。或者:


更新:由於你的代碼沒有它自己的HWND,嘗試SetWindowsHookEx(),如:

#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

你可以用「SetWindowsHookEx()」做一個例子嗎?我不知道這個函數到底做了什麼,在哪裏實現它以及如何使用它。對不起,如果我代理愚蠢的你,但即時通訊相對較新的C + +:/ – krobeN

+0

@ krobeN:回答更新 –

+0

非常感謝你!它確實幫助了很多;) – krobeN