WinEventHook не перехватывает события из определенного идентификатора процесса

Я создаю консольный процесс, а затем пытаюсь отслеживать его на наличие событий с помощью SetWinEventHook. Если я использую PID, связанный с созданным мной процессом, я никогда не улавливаю никаких событий. Если я установлю pid / thread на 0/0 (все процессы / потоки), то получу много результатов. Кажется, что-то не так в том, как я пытаюсь подключиться к конкретному процессу. Любые идеи были бы хорошы.

#include "stdafx.h"#include <windows.h>
#include <Oleacc.h>DWORD CreateChildProcess();
void InitializeMSAA(DWORD pid);
void ShutdownMSAA();
void SetConsoleBufferSize(DWORD processId, short columns, short rows);
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime);

HWINEVENTHOOK g_hook;

int main()
{
DWORD pid = CreateChildProcess();
Sleep(5000);
InitializeMSAA(pid);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

// Initializes COM and sets up the event hook.
void InitializeMSAA(DWORD pid)
{
// Initializes Component Object Model library
CoInitialize(NULL);

g_hook = SetWinEventHook(
EVENT_MIN, EVENT_MAX,       // Range of events (Console).
NULL,                                          // Handle to DLL.
HandleWinEvent,                                // The callback.
pid, 0,              // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT); // Flags.

//| WINEVENT_SKIPOWNPROCESS
}

// Unhooks the event and shuts down COM.
void ShutdownMSAA()
{
UnhookWinEvent(g_hook);
CoUninitialize();
}

// Callback function that handles events.
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime)
{
IAccessible * pAcc = NULL;
VARIANT varChild;
HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);
if ((hr == S_OK) && (pAcc != NULL))
{
BSTR bstrName;
pAcc->get_accName(varChild, &bstrName);
if (event == EVENT_SYSTEM_MENUSTART)
{
printf("Begin: ");
}
else if (event == EVENT_SYSTEM_MENUEND)
{
printf("End:   ");
}
printf("%S\n", bstrName);
SysFreeString(bstrName);
pAcc->Release();
}
}

// Creates a bash child process with i/o to a given console screen buffer
DWORD CreateChildProcess()
{
// In order to launch bash in System32, program must be built as x64
LPCTSTR applicationAddress = L"C:\\Windows\\System32\\bash.exe";

PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

// Set up members of the PROCESS_INFORMATION structure.
SecureZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));

// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
SecureZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);

// NB: Initial window size settings don't work for some reason.
auto minX = GetSystemMetrics(SM_CXMIN);
auto minY = GetSystemMetrics(SM_CYMIN);
siStartInfo.dwXSize = 200;
siStartInfo.dwYSize = 200;
//siStartInfo.dwXCountChars = 119;
//siStartInfo.dwYCountChars = 9;

//siStartInfo.wShowWindow = SW_HIDE;
siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE;
// | STARTF_USESHOWWINDOW | STARTF_USECOUNTCHARS

// Create the child process.
BOOL success = CreateProcess(
applicationAddress, // absolute path to the application
TEXT("-i"),         // command line
NULL,               // process security attributes
NULL,               // primary thread security attributes
TRUE,               // handles are inherited
CREATE_NEW_CONSOLE,               // creation flags
NULL,               // use parent's environment
NULL,               // use parent's current directory
&siStartInfo,       // STARTUPINFO pointer
&piProcInfo);       // receives PROCESS_INFORMATIONif (!success)
{
int lastError = GetLastError();
}

return piProcInfo.dwProcessId;
}

1

Решение

Если я использую PID, связанный с созданным мной процессом, я никогда
ловить любые события.

Вероятно, причина этого в том, что консольный процесс не владеет окном консоли. Окно консоли связано с conhost.exe (csrss.exe в версиях Windows до Win 7). Таким образом, сообщения, относящиеся к окну консоли, будут обрабатываться conhost.exe, а не процессом, который вы создали.

Если я установлю pid / thread на 0/0 (все процессы / потоки), я получу много
результатов.

Попробуйте установить PID для процесса conhost.exe, связанного с консольным приложением, которое вы запустили. Теперь вы должны получать события только из окна консоли.

Я не думаю, что существует прямой API для поиска связанного процесса conhost.exe, но вы можете попытаться перечислить все дочерние процессы нового процесса, пока не найдете «conhost.exe». Вероятно, вы должны сделать это в цикле, так как conhost.exe не будет там сразу после CreateProcess() вернулся.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector