C ++通过热键关闭我的进程

C++ closing my process via hotkey

我正在尝试编写一些代码 "virus"(只是一个有趣的笑话程序,它会弄乱光标并发出哔哔声)。但是,我想用我的 F9 键关闭这个过程。

这是我目前的情况:

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

我创建了一个线程,运行实现了这个功能。但是,当我 运行 我的整个代码并按 F9 时,过程仍然 运行s。只有当我按 2-3 次时,它才会出现错误:"Debug Error! abort() has been called."

如果有人知道我如何通过热键终止我的进程,那就太好了。

程序的全部代码如下:

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

GetAsyncKeyState() return有两条信息,但您只看其中一条,而且这条信息对您的代码用处不大。

根据 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.

当您 AND return 值与 0x8000 时,您仅测试 最高有效位 ,这意味着您正在测试仅当键当前处于关闭状态时 在调用 GetAsyncKeyState() 的确切时刻。这就是为什么您的代码通常需要多次按下或按住键一段时间才能检测到按键。您的代码中存在竞争条件。

您还应该 AND 带有 0x0001 的 return 值,以检查在您调用 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;
}