C++通过热键关闭我的进程
我试图编写一个小小的“病毒”(只是一个有趣的笑话程序,它随着光标四处乱动,并发出一些嘟嘟声)。但是,我想用我的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);
}
}
GetAsyncKeyState()
回报的两条信息,但你正在寻找只是其中之一,它是一个,是不是对你的代码是非常有用的。
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
与0x8000
返回值,如果正在测试只有最显著位,这意味着你正在测试只有在关键的是目前下跌在确切时刻即GetAsyncKeyState()
被调用。这就是为什么它通常需要几次按下,或者按住一段时间才能让您的代码检测按键。你的代码中有竞争条件。
您还AND
应该检查与0x0001
返回值,如果键被按下,并您致电GetAsyncKeyState()
的时间之间的发布:
if (GetAsyncKeyState(VK_F9) & 0x8001)
或者干脆:
if (GetAsyncKeyState(VK_F9) != 0)
那据说,你真正应该做的是实际监控键盘,让它告诉你何时按下键。或者:
使用
RegisterHotKey()
,处理WM_HOTKEY
窗口消息。使用
RegisterRawInputDevices()
,处理WM_INPUT
窗口消息。使用
SetWindowsHookEx()
来监视使用回调函数而不是窗口的按键(但您仍然需要消息循环)。
更新:由于你的代码没有它自己的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;
}
欢迎堆栈溢出。请花些时间阅读[The Tour](http://stackoverflow.com/tour),并参阅[帮助中心](http://stackoverflow.com/help/asking)中的资料,了解您可以在这里问。 –
大多数情况下,当你的进程处于睡眠状态时,你将会按下按键。您应该调查处理Windows消息。 –
你应该检查你的线程的行为,看看发生了什么。正如@NeilButterworth所说,线程可能在大多数时间都在睡觉。根据您添加的内容,它可能会执行一些其他任务,并且无法在导致您看到的错误时处理您的输入。或者你可能在创建线程时犯了一个错误。 – Javia1492