getting WindowHandle from CreateProcess
Hi,
I'm having a small problem using Create process. I'm trying to run an external program using createProcess(). This is working fine and the program (i'm testing it using calc) is loading ok. Now i want to get hold of the window handle (HWND__*) of the new process in this case calc.
I've tried the following code however it crashes out. Can anyone tell me whats going wrong with the code or another method to retrieve this handle?
Code:
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcessInfo;
GetStartupInfo(&siStartInfo);
CreateProcess(NULL, "Calc", NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo);
AppHook = FindProgWindow("Calculator");
FindProgWindow("prog name"); is a methos i have in a DLL. this is simply
Code:
DllExport HWND__* WINAPI FindProgWindow(CString progName)
{
return FindWindow(NULL, progName);
}
The program breaks out with the message
User breakpoint called from code at 0x7c901230
I have also tried replacing FindProgWindow("Calculator"); with FindWindow(NULL, "Calculator"); and this just returns 0.
Any Ideas?
thanks Matt.
Re: getting WindowHandle from CreateProcess
Well:
http://msdn.microsoft.com/library/de...findwindow.asp
What does "GetLastError" return when FindWindow returns 0?
Viggy
Re: getting WindowHandle from CreateProcess
Hi,
Thanks for the reply i've worked the problem out with using findWindow(). I simply needed to use the sleep(70) to wait until the program has loaded before i try and hook into.
It now adds my button to the calculator but is still causing problems as clicking it does nothing and it is not refreshing the button if another window is moved over it. I know the hooks are being created as neither are returning zero.
(These are events i have had working before as at first i had it as an Win32 application, however as i now don't want the form to appear i have rewritten it as a console application.)
Can anyone help?
Matt.
Re: getting WindowHandle from CreateProcess
Delving deeper the problem seems to be with my getMessage() command as once i have loaded the program added my button and hooked into it i then want to poll the program until WM_QUIT is retrieved, once this happens i can unhook and exit.
heres the code can anyone see what im doing wrong?
Code:
while( GetMessage(NULL,ThisHook,0,0) )
{
//do nothing until =0 and wm_quit is called
}
return 0;
Re: getting WindowHandle from CreateProcess
I think there was a command named GetHandleFromPid in FBSL, a basic language
Re: getting WindowHandle from CreateProcess
-
Quote:
Originally Posted by flynny1st
I simply needed to use the sleep(70) to wait until the program has loaded before i try and hook into.
Are you sure that sleeping 70ms is always enough (could be too much as well)?
Safer, once you have called CreateProcess and yo've got the handle to that process, you can use WaitForInputIdle to wait until that process has finished its initialization. -
Quote:
Originally Posted by flynny1st
Code:
FindWindow(NULL, progName);
Generally, the worst idea is to find a window given its text.
Better, in case of calc application you can use its main window class name ("SciCalc") or, better than better, once you have called CreateProcess and you've got the ID of main thread, you can use EnumThreadWindows
Here is a complete example:
Code:
HWND hWndCalc = NULL;
BOOL CALLBACK EnumThreadWndProc(HWND hWnd, LPARAM lParam)
{
hWndCalc = hWnd; // got the calc main window...
// ... start hooking or whatever, then...
return FALSE; // ...stop enum
}
// ...
STARTUPINFO siStartInfo = {0};
PROCESS_INFORMATION piProcessInfo = {0};
CreateProcessA(NULL, "Calc",
NULL, NULL, FALSE, 0, NULL, NULL,
&siStartInfo,&piProcessInfo);
if(0 == WaitForInputIdle(piProcessInfo.hProcess, 5000))
{
EnumThreadWindows(piProcessInfo.dwThreadId,
EnumThreadWndProc, NULL);
}
else
{
MessageBoxA(NULL, "Could not start calculator",
"Error", MB_OK|MB_ICONERROR);
}
// ...
Re: getting WindowHandle from CreateProcess
I wholeheartedly support the use of EnumThreadWindows. It has proven (to me) that it is the most reliable, and typically the most performant. I have had some issues during stress testing on Win-2000 Advanced Server, if I have over about 700 main windows open (and am nearly at resource exhaustion). But I have never found this to be a real world scenario.
Re: getting WindowHandle from CreateProcess
Quote:
Originally Posted by TheCPUWizard
But I have never found this to be a real world scenario.
I put that just for real life scenarios in that real world programmers tend to search for window caption texts. ;)
Re: getting WindowHandle from CreateProcess
ok, ovidiucucu i've followed what you said and i'm adding the callback function to my program.
However is it possible to add a callback function to a console application? or will i have to add it to my dll?
the code i have at the moment will is
Code:
int main(int argc, char* argv[])
{
...
STARTUPINFO siStartInfo = {0};
PROCESS_INFORMATION piProcessInfo = {0};
GetStartupInfo(&siStartInfo);
CreateProcess(NULL, "Calc", NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo);
if(WaitForInputIdle(piProcessInfo.hProcess, 5000) == 0)
{
EnumThreadWindows(piProcessInfo.dwThreadId, EnumThreadWndProc, NULL);
}
else
{
MessageBoxA(NULL, "Could not start calculator","Error", MB_OK|MB_ICONERROR);
}
}
BOOL CALLBACK EnumThreadWndProc(HWND hWnd, LPARAM lParam)
{
AppHook = hWnd; // got the calc main window
AppHInstance = FindWindowHInstance(AppHook);
AppProcessID = FindWindowProcess(AppHook);
ButtonHook = CreateButton(220, 63, 45, 30, AppHook, AppHInstance, NULL);
ButtonHInstance = FindWindowHInstance(ButtonHook);
ButtonProcessID = FindWindowProcess(ButtonHook);
if(AppProcessID != 0)
{
MouseHook = InstallMouseLauncher(NULL, ButtonProcessID, ButtonHook);
EventsHook = InstallEventsLauncher(ButtonHInstance, ButtonProcessID, ButtonHook, ThisHook);
sprintf(hook, "MouseHook %d, Events %d", MouseHook, EventsHook);
MessageBox(NULL,hook,NULL,0);
}
return FALSE; // ...stop enum
}
however it compiling with this gives the following errors.
error C2065: 'EnumThreadWndProc' : undeclared identifier
error C2373: 'EnumThreadWndProc' : redefinition; different type modifiers
any ideas? thanks for the help.
Matt
Re: getting WindowHandle from CreateProcess
Hi,
Ok i've pulled the callback method into my dll and its now working fine.
thanks for the help.
Matt.