Is it possible to wait until the main window of the process has been constructed?

  • Thread starter Thread starter Sagar R. Kapadia
  • Start date Start date
S

Sagar R. Kapadia

Guest
I have an app which installs a hook into a process using its processId, to track keyboard and mouse events.

I get the processId using Event Tracing for Windows (ETW) in C# code, which then calls a COM [ATL] out of process server [EXE] to inject the DLL.

I need to find the main window of the process. However, sometimes, the window has not yet been created when I have the processId and so enum windows fails. Is there a way to wait until the main window of the process is created, or do I have to keep trying until I find the window

I wish to replace the call to Sleep(5000) in FindMainWindow() by something more reliable. That is, I need to wait indefinitely until the main window has been created. How do I do that?

The code is as below


C# ETW Code to get processId as soon as the process is created.



var processProviderGuid = TraceEventProviders.GetProviderGuidByName("Microsoft-Windows-Kernel-Process");

session.EnableProvider(processProviderGuid, TraceEventLevel.Informational, 0x10);

source.Process();

Once I have the processId, I try to find the main window, and inject the hook, as shown below



BOOL FindTargetWindowAndInjectHook(DWORD targetProcessId,LPCWSTR lpWindowName)
{
//Sleep for sometime to allow the main window to be created
Sleep(5000);
HWND hWnd = FindMainWindow(targetProcessId);
if (hWnd)
{
cout << "Found Window:" << lpWindowName << endl;
//Inject Hook -code omitted
}



I use the following code to find the main window handle

struct handle_data {
DWORD process_id;
HWND window_handle;
};

BOOL is_main_window(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}


BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle))
return TRUE;
cout << "Found a match" << endl;
data.window_handle = handle;
return FALSE;
}



HWND FindMainWindow(DWORD process_id)
{
handle_data data;
data.process_id = process_id;
data.window_handle = 0;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.window_handle;
}

Continue reading...
 
Back
Top