C++;-如何退出没有窗口的程序? 我是C++新手,我自己做了一个小程序,可以通过在键盘上键入命令来启动程序。为了能够随时启动程序,我决定设置一个低级键盘挂钩,它可以跟踪按键的笔划,并在检测到特定命令时启动特定程序。简单的windows程序用于安装钩子,windows没有显示,因为我只需要钩子在后台监听

C++;-如何退出没有窗口的程序? 我是C++新手,我自己做了一个小程序,可以通过在键盘上键入命令来启动程序。为了能够随时启动程序,我决定设置一个低级键盘挂钩,它可以跟踪按键的笔划,并在检测到特定命令时启动特定程序。简单的windows程序用于安装钩子,windows没有显示,因为我只需要钩子在后台监听,c++,windows,keyboard-hook,C++,Windows,Keyboard Hook,到目前为止,它工作正常,但是,一个小问题,但恼人的是我必须通过Windows任务管理器终止程序,这是相当不方便的。我通过按F7键成功地卸载了钩子,但似乎没有显示的windows程序是钩子的父程序,因此钩子无法退出windows程序。而我希望他们都通过按键终止。希望我已经说清楚了 有没有办法让我从钩子向windows程序发送一条消息,要求它退出?或者我可以在hook程序中终止它们 提前谢谢 以下是窗口程序的代码: #include <windows.h> #include "short

到目前为止,它工作正常,但是,一个小问题,但恼人的是我必须通过Windows任务管理器终止程序,这是相当不方便的。我通过按F7键成功地卸载了钩子,但似乎没有显示的windows程序是钩子的父程序,因此钩子无法退出windows程序。而我希望他们都通过按键终止。希望我已经说清楚了

有没有办法让我从钩子向windows程序发送一条消息,要求它退出?或者我可以在hook程序中终止它们

提前谢谢

以下是窗口程序的代码:

#include <windows.h>
#include "shortcut.h"

#pragma comment( lib, "libhook.dll.a")          // Link Hook.lib to the project

long WINAPI WndProc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
    switch(wMessage)
    {
        case WM_DESTROY:
            InstallHook(FALSE);     // Unhook
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, wMessage, wParam, lParam);
    }
    return 0;

}
BOOL FileExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
         !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASS wndclass;
    HANDLE hMutex = NULL;
    char szAppName[20] = "shortcut";

    hMutex = CreateMutex(NULL,TRUE,szAppName); //启动多线程
    int dwRet = GetLastError();
    if (hMutex)
    {
        if (dwRet == ERROR_ALREADY_EXISTS)
        {
            MessageBox(NULL, "Program is already runing.", "Oops!", MB_OK | MB_ICONINFORMATION);
            CloseHandle(hMutex);
            return FALSE;
        }
    }
    wndclass.style=0;
    wndclass.lpfnWndProc=(WNDPROC)WndProc;
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hInstance=hInstance;
    wndclass.hIcon=NULL;
    wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
    wndclass.lpszMenuName=NULL;
    wndclass.lpszClassName=(LPSTR)szAppName;

    if(!RegisterClass(&wndclass))
        return FALSE;
    if (!FileExists("\\ShortCuts.txt"))
    {
        MessageBox(NULL, "Missing file: cannot load shortcut settings file.(Shortcuts.txt)", "ERROR",MB_OK|MB_ICONINFORMATION);
        exit(1);
    }
    if (!InstallHook(TRUE))
        exit(1);

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}
#包括
#包括“shortcut.h”
#pragma注释(lib,“libhook.dll.a”)//将Hook.lib链接到项目
长WINAPI WndProc(HWND-HWND、UINT-wMessage、WPARAM-WPARAM、LPARAM-LPARAM)
{
开关(wMessage)
{
案例WM_销毁:
InstallHook(FALSE);//取消挂钩
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hWnd、wMessage、wParam、lParam);
}
返回0;
}
BOOL文件存在(LPCTSTR szPath)
{
DWORD dwAttrib=GetFileAttributes(szPath);
返回(dwAttrib!=无效的文件属性&&
!(dwAttrib&FILE_属性_目录));
}
int WINAPI WinMain(HINSTANCE HINSTANCE,
HINSTANCE HPPreInstance、LPSTR lpszCmdLine、int nCmdShow)
{
味精;
WNDCLASS WNDCLASS;
句柄hMutex=NULL;
char szAppName[20]=“快捷方式”;
hMutex=CreateMutex(NULL,TRUE,szAppName)//启动多线程
int dwRet=GetLastError();
if(hMutex)
{
如果(dwRet==错误\u已存在)
{
MessageBox(NULL,“程序已在运行。”,“Oops!”,MB|U OK | MB|U图标信息);
密柄(hMutex);
返回FALSE;
}
}
wndclass.style=0;
lpfnWndProc=(WNDPROC)WNDPROC;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=NULL;
wndclass.hCursor=LoadCursor(空,IDC_箭头);
wndclass.hbrBackground=(HBRUSH)GetStockObject(灰色画笔);
wndclass.lpszMenuame=NULL;
wndclass.lpszClassName=(LPSTR)szAppName;
if(!RegisterClass(&wndclass))
返回FALSE;
如果(!FileExists(“\\ShortCuts.txt”))
{
MessageBox(NULL,“缺少文件:无法加载快捷方式设置文件。(Shortcuts.txt)”,“错误”,MB_OK | MB_图标信息);
出口(1);
}
如果(!InstallHook(TRUE))
出口(1);
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
返回msg.wParam;
}
以下是钩子程序的代码:

// Hook- a project to create the DLL and LIB files.
// Microsoft Visual C++ 6.0 and above steps:
// 1. Create a new Win32 Dynamic Link - Library project.
// 2. Add hook.cpp and hook.h to the project.
// 3. There is no step 3 :-). Just build your project and you will find
// a Hook.dll and Hook.lib file in your map.

#include <windows.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <ctime>
#include <map>
#include <process.h>
using namespace std;


HHOOK hHook;
HINSTANCE ghDLLInst=0;
const char startChar = ';';
bool bChecking = false;
string cmd;
typedef map<string,string> COMMANDMAP;
COMMANDMAP mShortcut;
string logfilename="log.txt";
ofstream LOG;

__declspec(dllexport)int InstallHook(BOOL bCode);

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwFunction, LPVOID lpNot)
{
    ghDLLInst=(HINSTANCE)hModule;
    return TRUE;
}

DWORD WINAPI Runsystem(LPVOID lpParam)
{
    WinExec((LPCSTR)lpParam, SW_SHOW);
}

string gettime()
{
    time_t curTime;
    struct tm *locTime;
    char buf[80];
    time(&curTime);
    locTime=localtime(&curTime);
    strftime(buf,80,"%Y-%m-%d %H:%M:%S",locTime);
    string s=buf;
    return s;
}

ostream& tout()
{
    return LOG<< gettime()<< ": ";
}

void StartCheck()
{
    bChecking=true;
    cmd.clear();
}
void EndCheck()
{
    bChecking=false;
    cmd.clear();
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{

    if ((wParam == WM_KEYDOWN) && (nCode >= HC_ACTION))                         // Only record when key pressed
    {
    KBDLLHOOKSTRUCT *pStruct = (KBDLLHOOKSTRUCT*)lParam;
    switch (pStruct->vkCode)
    {
        case VK_RETURN:
        {
            if (bChecking)
            {
            COMMANDMAP::iterator it;
            it=mShortcut.find(cmd);
            if (it!=mShortcut.end())
            {
                tout()<<"received command \'"<<cmd<<"\', executing \'"<<it->second.c_str()<<endl;
                CreateThread(NULL, 0, Runsystem, (void*)it->second.c_str(),0,NULL);
            }
            else {
                tout()<<"received command \'" <<cmd<<"\', no matching."<<endl;
            }
            }
            EndCheck();
            break;
        }
        case VK_F7:
        {
            InstallHook(false);
            break;
        }
        default:            // Normal keys, convert them
        {
            BYTE KeyboardState[256];
            GetKeyboardState(KeyboardState);
            WORD CharValue;
            if(ToAscii(pStruct->vkCode, pStruct->scanCode,KeyboardState,&CharValue,0) > 0)      // Convert to char.
            {
            char character=char(CharValue);
//          tout()<<"received keyCode: "<<pStruct->vkCode<< " char: "<< character<<endl;
            if (bChecking)
            {
                cmd+=character;
            }
            if (!bChecking && (character == startChar))
            {
//              tout()<<"Start checking..."<<endl;
                StartCheck();
            }
            }
            break;
        }
    }
    }
    return (int)CallNextHookEx(hHook, nCode, wParam, lParam);
}

bool readline(ifstream &fin,string &sline)
{
    do
    {
    getline(fin,sline);
    } while (!fin.eof() && ((sline[0]=='/' && sline[1]=='/') || sline.empty()));

    return fin.eof()?false:true;
}

// __declspec(dllexport) means that this function must be exported to a dll file.
__declspec(dllexport)int InstallHook(BOOL bCode)
{
    if(bCode)
    {
    // initialize shortcuts
    ifstream fin;
    LOG.open(logfilename.c_str(),ios_base::app);
    tout()<<"Reading config file."<<endl;
    fin.open("ShortCuts.txt");
    if (fin)
    {
        string scmd,spath;
        char oneline[256];
        while(readline(fin,scmd)&&readline(fin,spath))
        {
        mShortcut[scmd]=spath;
//      LOG<<scmd<<','<<spath<<endl;
        }
        fin.close();
        tout()<<"OK, "<<mShortcut.size()<<" shortcuts loaded."<<endl;
    }
    else
    {
        tout()<<"ERROR"<<endl;
        LOG.close();
        exit(0);
    }


    hHook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc,   // Start the keyboard hook.
        (HINSTANCE)GetModuleHandle(NULL), NULL);

    if(!hHook)
    {
        tout()<<"Install hook failed."<<endl;
        return 0;
    }
    else
    {
        tout()<<"Install hook successful."<<endl;
        return 1;
    }
    }
    else
    {
    if (MessageBox(NULL,"Are you sure to exit KeyShortcut?","Exit",MB_YESNO|MB_ICONWARNING)==IDYES)
    {
        tout()<<"Uninstall hook successful."<<endl;
        LOG.close();
        return UnhookWindowsHookEx(hHook); // Unhook the keyboardhook.
    }
    }
}
//Hook-用于创建DLL和LIB文件的项目。
//微软Visual C++ 6及以上步骤:
// 1. 创建新的Win32动态链接库项目。
// 2. 将hook.cpp和hook.h添加到项目中。
// 3. 没有步骤3:-)。只要建立你的项目,你就会发现
//地图中的Hook.dll和Hook.lib文件。
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
哈哈哈哈;
HINSTANCE ghDLLInst=0;
常量char startChar=';';
bool b检查=错误;
字符串cmd;
typedef-map命令图;
命令映射mShortcut;
字符串logfilename=“log.txt”;
流测井曲线;
__declspec(dllexport)intinstallhook(boolbcode);
布尔APIENTRY DllMain(句柄hModule、DWORD dwFunction、LPVOID lpNot)
{
ghDLLInst=(HINSTANCE)hModule;
返回TRUE;
}
DWORD WINAPI运行系统(LPVOID lpParam)
{
WinExec((LPCSTR)lpParam,西南展览);
}
字符串gettime()
{
时间短了;
struct tm*locTime;
char-buf[80];
时间(&curTime);
locTime=本地时间(&curTime);
strftime(buf,80,“%Y-%m-%d%H:%m:%S”,locTime);
字符串s=buf;
返回s;
}
ostream&tout()
{
返回LOGvkCode)
{
案例VK_返回:
{
如果(b检查)
{
COMMANDMAP::迭代器;
it=mShortcut.find(cmd);
if(it!=mShortcut.end())
{
tout()例如,您可以使用API函数为系统设置自己的热键,然后在程序中处理此热键的消息(无窗口)

添加:
如果您想将退出消息从一个进程发送到另一个进程,那么您的朋友是

PostQuitMessage()还不够?谢谢您,Johnny,RegisterHotKey函数非常有用,它完美地解决了我的问题。再次感谢(: