gpt4 book ai didi

c++ - SetWinEventHook 与 CreateProcess,C++

转载 作者:搜寻专家 更新时间:2023-10-31 01:06:29 25 4
gpt4 key购买 nike

我正在使用 CreateProcess 打开一个窗口,但我在理解 SetWinEventHook 时遇到了很多麻烦。

在调用函数中,我有:

HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT );

BOOL result = CreateProcess(0, arguments,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo)

if (hook) {
UnhookWinEvent(hook);
}

创建过程顺利进行,但未调用链接到 SetWinEventHook 的 WinEventProc 函数。为了让 WinEventProc 被调用,我尝试了这样的事情:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0);

在 createProcess 调用之后,但我不知道如何结束 while 循环以便它连续进行。

我读了很多书,但我不明白如何使用 SetWinEventHook 来捕获由 CreateProcess 启动的进程。感谢您的帮助!

最佳答案

您可能需要完整且有效的事件循环 - 尝试:

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

如果您的应用程序不是 GUI 应用程序——或者更具体地说,如果您除了 Hook 之外不需要事件循环——您可以添加另一个线程并在那里使用上面的事件循环(以及所有 Hook 和取消 Hook )我想),或者将 PeekMessageGetMessage 结合使用来创建非阻塞事件循环并定期调用它。

其次,您不应在调用 CreateProcess 后直接删除 Hook 。窗口的创建通常发生在程序完全加载和初始化之后,这个过程可能需要一段时间。 CreateProcess 异步工作,这意味着它不会在退出之前等待所有这些发生。

第三,为了能够接收任何类型的 Hook 消息,您的消息循环需要在 SetWinEventHookUnhookWinEvent 之间执行 - 在任何其他情况下您都不会得到任何东西.

最后,为了避免来自其他进程的消息被传递到您的进程,您应该使用 CREATE_SUSPENDED 标志启动您的应用程序,使用适当的进程 ID 启动您的 Hook ,然后通过使用恢复进程执行ResumeThread 具有从 CreateProcess 获得的主线程句柄。

总体而言,它应该是这样的:

BOOL result = CreateProcess(0, arguments,
NULL, NULL, FALSE, CREATE_SUSPENDED, NULL,
NULL, &StartupInfo, &ProcessInfo);

HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, WinEventProc, ProcessInfo.dwProcessId, 0, WINEVENT_OUTOFCONTEXT );

ResumeThread(ProcessInfo.hThread);

// If you don't have an event loop function in your application already, then you could insert a temporary one here.
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

如果您的应用程序不是事件驱动的 - 只是常规的顺序应用程序,那么您应该定期调用上述事件循环直到您的 WinEventProc 执行 - 您可能应该添加一些安全变量以查看它是否已经执行.另一个好主意可能是包括一些超时(2-3 分钟?),以防没有发布任何事件(应用程序崩溃,应用程序由于某种原因没有创建对象)。为简单起见,我还跳过了任何错误检查。

你的钩子(Hook)程序应该做类似的事情:

void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime)
{
// This will handle the re-entrance problem nicely.
UnhookWinEvent(hWinEventHook);

// Do wathever you need to do with a window here.
[...]

}

编辑:

至于跳过消息循环——是的,这就是这个消息循环应该做的。

哪种消息循环最适合您取决于您​​的程序构造 - 如果您已经运行了一个偶数循环(Qt、MFC 等 GUI 框架......通常已经为您实现),那么您不需要无论如何添加任何。如果您希望您的应用程序等到 WinEvent 交付,那么您应该这样做:

//Global variable for stop-condition:
bool docontinue = false;

void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime)
{
// This will handle the re-entrance problem nicely.
UnhookWinEvent(hWinEventHook);

// Do wathever you need to do with a window here.
[...]
docontinue = false;
}

钩子(Hook)函数应该做的:

// In hooking function use:
docontinue = true;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (!docontinue)
break;
}

这是最幼稚的方法,它有几个缺点,但如果您只需要执行一个简单的操作,那么它可能对您来说就足够了。

关于c++ - SetWinEventHook 与 CreateProcess,C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20732086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com