unit xAPIUtils;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
function FindWindowByFilename(
const Filename:
string; Path: Boolean): HWND;
procedure KillProcess(hWindowHandle: HWND);
implementation
uses TlHelp32, PSApi;
//==============================================================================
function FindWindowByProcessId(ProcessId: DWORD): HWND;
type
PParam = ^TParam;
TParam =
record
ProcessId: DWORD;
WndHandle: HWND;
end;
// Callback function
function EnumWindowsProc(Wnd: HWND;
var Param: TParam): BOOL;
stdcall;
var
ProcessId: DWORD;
begin Result := True;
// visible only
if IsWindowVisible(Wnd)
then
begin
ProcessId := 0;
GetWindowThreadProcessId(Wnd, @ProcessId);
if (ProcessId = Param.ProcessId)
then
begin
Param.WndHandle := Wnd;
Result := False;
end;
end;
end;
var
Param: TParam;
begin
Param.ProcessId := ProcessId;
Param.WndHandle := 0;
EnumWindows(@EnumWindowsProc, LPARAM(@Param));
Result := Param.WndHandle;
end;
//==============================================================================
function FindWindowByImage9x(
const Filename:
string; Path: Boolean): HWND;
var
ProcSnap: THandle;
ProcEntry: TProcessEntry32;
ModSnap: THandle; ModEntry:
TModuleEntry32;
begin
Result := 0;
// Get list of processes (IDs)
ProcSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (ProcSnap <> INVALID_HANDLE_VALUE)
and (ProcSnap <> 0)
then
try
// Loop through process list
ZeroMemory(@ProcEntry, SizeOf(TProcessEntry32));
ProcEntry.dwSize := SizeOf(TProcessEntry32);
if Process32First(ProcSnap, ProcEntry)
then
repeat
// Get list of modules
ModSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcEntry.th32ProcessID);
if (ModSnap <> INVALID_HANDLE_VALUE)
and (ModSnap <> 0)
then
try
// get the first module only
// ( let's call it image-used-to-create-the-process )
ZeroMemory(@ModEntry, SizeOf(TModuleEntry32));
ModEntry.dwSize := SizeOf(TModuleEntry32);
if Module32First(ModSnap, ModEntry)
then
begin
// Compare _case_insensitive_
if Path
and (StrIComp(ModEntry.szExePath, PChar(Filename)) = 0)
then
// with path
Result := FindWindowByProcessId(ProcEntry.th32ProcessID);
if (
not Path)
and (StrIComp(ModEntry.szModule, PChar(Filename)) = 0)
then
// without path
Result := FindWindowByProcessId(ProcEntry.th32ProcessID);
end;
finally
CloseHandle(ModSnap);
end;
until (Result <> 0)
or not Process32Next(ProcSnap, ProcEntry);
finally
CloseHandle(ProcSnap);
end;
end;
//==============================================================================
function FindWindowByImageNt(
const Filename:
string; Path: Boolean): HWND;
type
PProcList = ^TProcList;
TProcList =
array [Word]
of DWORD;
var
ListSize: DWORD;
ListNeed: DWORD;
ProcList: PProcList;
Loop: Word;
Process: THandle;
Module: HMODULE;
ModName:
array [0..MAX_PATH]
of Char;
begin
Result := 0;
ListSize := 1024 * SizeOf(DWORD);
ProcList := GetMemory(ListSize);
try
// Get list of processes (IDs)
ListNeed := 0;
while EnumProcesses(@ProcList[0], ListSize, ListNeed)
and (ListNeed >= ListSize)
do
begin
Inc(ListSize, 1024 * SizeOf(DWORD));
FreeMemory(ProcList);
ProcList := GetMemory(ListSize);
if not Assigned(ProcList)
then
Exit;
end;
// Loop through process list
for Loop := 0
to ListNeed
div SizeOf(DWORD) - 1
do
begin
// Open the process (to read module)
Process := OpenProcess(PROCESS_QUERY_INFORMATION
or PROCESS_VM_READ,
False, ProcList[Loop]);
if (Process <> 0)
then
try
// get the first module only
// ( let's call it image-used-to-create-the-process )
ListSize := SizeOf(DWORD);
ListNeed := 0;
if EnumProcessModules(Process, PDWord(@Module), ListSize, ListNeed)
and
(ListNeed >= ListSize)
then
begin
ModName[0] := #0;
// Get the filename with/without path
if Path
then
GetModuleFileNameEx(Process, Module, ModName, SizeOf(ModName))
else
GetModuleBaseName(Process, Module, ModName, SizeOf(ModName));
// Compare _case_insensitive_
if (StrIComp(ModName, PChar(Filename)) = 0)
then
begin
// Find first window by process id
Result := FindWindowByProcessId(ProcList[Loop]);
if (Result <> 0)
then
Break;
end;
end;
finally
CloseHandle(Process);
end;
end;
finally
if Assigned(ProcList)
then
FreeMemory(ProcList);
end;
end;
//==============================================================================
function FindWindowByFilename(
const Filename:
string; Path: Boolean): HWND;
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT)
and (Win32MajorVersion <= 4)
then
// Windows NT 4.0 or earlier (using PSApi)
Result := FindWindowByImageNt(Filename, Path)
else
// else (using TlHelp32)
Result := FindWindowByImage9x(Filename, Path);
end;
//==============================================================================
procedure KillProcess(hWindowHandle: HWND);
var
hprocessID: INTEGER;
processHandle: THandle;
DWResult: DWORD;
begin
// SendMessageTimeout(hWindowHandle, WM_CLOSE, 0, 0,
// SMTO_ABORTIFHUNG or SMTO_NORMAL, 5000, DWResult);
if true
or isWindow(hWindowHandle)
then
begin
// PostMessage(hWindowHandle, WM_QUIT, 0, 0);
{ Get the process identifier for the window}
GetWindowThreadProcessID(hWindowHandle, @hprocessID);
if hprocessID <> 0
then
begin
{ Get the process handle }
processHandle := OpenProcess(PROCESS_TERMINATE
or PROCESS_QUERY_INFORMATION,
False, hprocessID);
if processHandle <> 0
then
begin
{ Terminate the process }
TerminateProcess(processHandle, 0);
CloseHandle(ProcessHandle);
end;
end;
end;
end;
end.