André Murta
asked on
Process name for the active window in Windows 8/10
Hello,
I need to capture the name of the application that is in foreground during a certain moment at the user's Windows session. I'm trying the following approach in order to get that:
What happens is when the foreground application is a Windows 10 app, this function always return 'ApplicationFrameHost.exe' as the captured process name. Doing some Google search I found the following web page that has a C code that solves that problem:
Process name for the active window in Windows 8/10
I'm trying to rewrite the presented code in Delphi (Object Pascal), but without success. The LPARAM argument at the 'EnumChildWindowsCallback' function is always being filled with invalid data. Its a shame, but I admmit that I do not have enough knowledge about Object Pascal Pointers. What I'm trying to do is:
But I'm facing an exception due to the test inside the 'EnumChildWindowsCallback' function never being succeeded, the callback is being called until a "Stack Overflow" exception occurs:
Is there a way to obtain the correct Windows 10 processes names using Delphi? I'm not concerned in fix my "code porting" attempt. If there is already an example code (written in Object Pascal) that returns the correct process name it would be just great, but currently I'm unable to find such example in the web.
I need to capture the name of the application that is in foreground during a certain moment at the user's Windows session. I'm trying the following approach in order to get that:
function ProcessName(AID: Cardinal): String;
var
Snapshot: THandle;
ProcessEntry: TProcessEntry32;
begin
Result := '';
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
try
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
if not Process32First(Snapshot, ProcessEntry) then
Exit;
repeat
if (ProcessEntry.th32ProcessID = AID) then
begin
Result := ProcessEntry.szExeFile;
break;
end;
until not Process32Next(Snapshot, ProcessEntry);
finally
CloseHandle(Snapshot);
end;
end;
What happens is when the foreground application is a Windows 10 app, this function always return 'ApplicationFrameHost.exe' as the captured process name. Doing some Google search I found the following web page that has a C code that solves that problem:
Process name for the active window in Windows 8/10
I'm trying to rewrite the presented code in Delphi (Object Pascal), but without success. The LPARAM argument at the 'EnumChildWindowsCallback' function is always being filled with invalid data. Its a shame, but I admmit that I do not have enough knowledge about Object Pascal Pointers. What I'm trying to do is:
type
TWindowInfo = record
ownerpid: DWORD;
childpid: DWORD;
end;
PWindowInfo = ^TWindowInfo;
...
function EnumChildWindowsCallback(hwd: HWND; lp: LPARAM): Boolean; stdcall;
var
info: PWindowInfo;
pid: DWORD;
begin
info := PWindowInfo(lp);
pid := 0;
EnumChildWindowsCallback(hwd, pid);
if (pid <> info^.ownerpid) then
info^.childpid := pid;
Result := true;
end;
...
procedure TfrmMain.Timer1Timer(Sender: TObject);
var
active_window: HWND;
active_process: THANDLE;
info: TWindowInfo;
image_name: array[0..MAX_PATH] of Char;
bufsize: DWORD;
begin
active_window := GetForegroundWindow();
info.ownerpid := 0;
info.childpid := 0;
if GetWindowThreadProcessId(active_window, @info.ownerpid) <> 0 then
begin
info.childpid := info.ownerpid;
EnumChildWindows(active_window, @EnumChildWindowsCallback, LPARAM(Addr(info)));
active_process := OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
bufsize := MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, @bufsize);
AddLog('Timer1Timer()', 'host pID: '+IntToStr(active_process)+', EXE: '+String(image_name));
CloseHandle(active_process);
end;
end;
But I'm facing an exception due to the test inside the 'EnumChildWindowsCallback' function never being succeeded, the callback is being called until a "Stack Overflow" exception occurs:
if (pid <> info^.ownerpid) then
info^.childpid := pid;
Is there a way to obtain the correct Windows 10 processes names using Delphi? I'm not concerned in fix my "code porting" attempt. If there is already an example code (written in Object Pascal) that returns the correct process name it would be just great, but currently I'm unable to find such example in the web.
Can't you use a window spy for that?
ASKER
Not really. It must be done by my app, since this single app is part of a bigger system that analyzes all the motions of each company user, during it's Windows session.
Yeah I realised this later on, sorry lol ;) Good luck!
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.