That might indeed sound pretty complicated but there are a lot of free code snippets for "How do I find a window
handle if I only have the process ID?". It's also what I'd strongly suggest since TerminateProcess is pretty much like shooting someone in the head... from behind.
Always give the other application a fair change to shut down and clean up. This also includes the remaining unwanted tray icon (blood splatter?).
Here's an excerpt of how I search for the Window
handle of a process I only have the ID of for later sending a WM_CLOSE message. I believe it has a few shortcomings like only returning the first window that matches but it always served me well.
Delphi-Quellcode:
TEnumInfo = record
ProcessID: DWORD;
HWND: THandle;
end;
//Prozess-ID muss stimmen. Das Fenster muss nicht aktiviert oder sichtbar sein!
function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
var
PID: DWORD;
begin
GetWindowThreadProcessID(Wnd, @PID);
Result := (PID <> EI.ProcessID);
//or IsWindowVisible(WND)) or (not IsWindowEnabled(WND));
if not Result then EI.HWND := WND; //Die Enumeration durch alle Fenster
// geht NUR weiter, wenn diese Funktion TRUE liefert!
end;
//Wird kein Fenster gefunden, ist die Rückgabe 0
function FindFirstWindow(PID: DWORD): DWORD;
var
EI: TEnumInfo;
begin
EI.ProcessID := PID;
EI.HWND := 0;
EnumWindows(@EnumWindowsProc, Integer(@EI));
Result := EI.HWND;
end;
Most of it was probably "borrowed" from this very forum.
You can then just get the Windowhandle
evilWindowHandle := FindFirstWindow(evilProcess.dwProcessId);
and send a WM_CLOSE:
PostMessage(evilWindowHandle, WM_CLOSE, LPARAM(False), WPARAM(False));