【问题标题】:C++ closing my process via hotkey [duplicate]C ++通过热键关闭我的进程[重复]
【发布时间】:2017-11-29 14:56:27
【问题描述】:

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

这是我目前所拥有的:

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

【问题讨论】:

  • 欢迎来到 Stack Overflow。请花时间阅读The Tour 并参考Help Center 中的材料,您可以在这里问什么以及如何问。
  • 大多数情况下,当您的进程处于睡眠状态时,您将按下该键。您应该调查处理 Windows 消息。
  • 你应该检查你的线程的行为,看看发生了什么。正如@NeilButterworth 所说,线程可能大部分时间都在睡觉。根据您添加的其他内容,它可能正在执行其他任务,并且当时无法处理您的输入,从而导致您看到的错误。或者你可能在创建线程时犯了一个错误。
  • 这也将有助于显示其他代码,最好是线程,因为您已经测试了您的函数并表示它有效。这意味着您的问题很可能与线程有关。
  • @Javia1492 我的其他线程(randomCursorMovement、Beeps)没有中断 kill 线程。我认为这与函数“exit(0);”有关。但是我知道的不多,因为我刚开始接触c++。

标签: c++ windows winapi hotkeys kill-process


【解决方案1】:

GetAsyncKeyState() 返回两条信息,但您只查看其中一条,它对您的代码不是很有用。

根据documentation

如果函数成功,返回值指定自上次调用 GetAsyncKeyState 后是否按下了键,以及该键当前是向上还是向下。如果设置了最高有效位,则按键按下,如果设置了最低有效位,则在上一次调用 GetAsyncKeyState 之后按键被按下

当你 AND0x8000 的返回值时,你只测试最高有效位,这意味着你只测试密钥当前是否正确时刻 GetAsyncKeyState() 被调用。这就是为什么您的代码通常需要多次按下或按住键一段时间才能检测到按键。您的代码中有竞争条件。

您还应该AND0x0001 的返回值来检查在您调用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;
}

【讨论】:

  • 你能用“SetWindowsHookEx()”做一个例子吗?我不知道这个函数到底是做什么的,在哪里实现它以及如何使用它。对不起,如果我对你装傻,但我对 c++ 比较陌生:/
  • @krobeN:答案已更新
  • 非常感谢!它真的很有帮助;)
猜你喜欢
  • 2018-03-02
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 2016-06-04
  • 2013-06-24
  • 2012-11-20
  • 1970-01-01
相关资源
最近更新 更多