How to get applications from Windows Task manager (Applications Tab) + their locations on HDD from Delphi

chubbyk picture chubbyk · Aug 1, 2010 · Viewed 7.3k times · Source

I would like to get list of programs running and visible in windows task manager's Applications Tab (not processes tab) and get their locations on HDD?
I need it to be done in Delphi. Anybody can help?

Answer

vcldeveloper picture vcldeveloper · Aug 1, 2010

As far as I know, Application tab in Task Manager is a list of top-level windows which are not owned by other windows, have no parent, and are not tool windows. In my Process Info, I have a unit called AppInfo.pas which returns a list of windows with such characteristics, and the list matches what you see in Task Manager. Here is the main part of the code which is written as a call-back function for EnumWindows API function:

{$IFDEF DELPHI2007UP}
class function TAppWindowCollection.EnumWinProc(wHandle: HWND; lparam: integer): Bool;
{$ELSE}
function EnumWinProc(wHandle: HWND; lparam: integer): Bool; stdcall;
{$ENDIF}
Const
  MAX_TEXT = MAX_PATH;
var
  WindowItem : TWindowItem;
  strText,strClass : array [0..MAX_TEXT] of char;
  IsAppMainWin : Boolean;
begin
  //Check if the window is a visible application main window.
  IsAppMainWin := IsWindowVisible(wHandle)          AND                        //Visible
                  (GetWindow(wHandle,GW_OWNER) = 0) AND                        //Not owned by other windows
                  (GetParent(wHandle) = 0)          AND                        //Does not have any parent
                  (GetWindowLong(wHandle,GWL_EXSTYLE) AND WS_EX_TOOLWINDOW = 0); //Not a tool window

  if IsAppMainWin then
  begin
    WindowItem := TAppWindowCollection(lparam).Add;

    GetWindowText(wHandle,strText,MAX_TEXT);
    GetClassName(wHandle,strClass,MAX_TEXT);

    WindowItem.FCaption := strText;
    WindowItem.FHandle := wHandle;
    WindowItem.FWindowClass := strClass;
    GetWindowThreadProcessId(wHandle,WindowItem.FProcessID);
  end;

  Result := True;
end;

For the full source code, you can refer to AppInfo.pas.

and get their locations on HDD

These are just windows. If you want to get path of EXE file corresponding to each item, you should first find the process which is owning this window, using GetWindowThreadProcessID API function. That is what I did in the above code. Once you have the process ID, you can get a process handle from it, and enumerate its modules. The first module is the main EXE file. I implemented that in my TProcessInfo component which is included in the same package with AppInfo.pas.