10

I want to get a list with all the threads (except the main, GUI thread) from within my application in order to do some action(s) with them. (set priority, kill, pause etc.) How to do that?

vcldeveloper
  • 7,399
  • 2
  • 33
  • 39
John Thomas
  • 4,075
  • 3
  • 29
  • 41

5 Answers5

14

Another option is use the CreateToolhelp32Snapshot,Thread32First and Thread32Next functions.

See this very simple example (Tested in Delphi 7 and Windows 7).

program ListthreadsofProcess;

{$APPTYPE CONSOLE}

uses
  PsAPI,
  TlHelp32,
  Windows,
  SysUtils;

function GetTthreadsList(PID:Cardinal): Boolean;
var
  SnapProcHandle: THandle;
  NextProc      : Boolean;
  TThreadEntry  : TThreadEntry32;
begin
  SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); //Takes a snapshot of the all threads
  Result := (SnapProcHandle <> INVALID_HANDLE_VALUE);
  if Result then
  try
    TThreadEntry.dwSize := SizeOf(TThreadEntry);
    NextProc := Thread32First(SnapProcHandle, TThreadEntry);//get the first Thread
    while NextProc do
    begin
      if TThreadEntry.th32OwnerProcessID = PID then //Check the owner Pid against the PID requested
      begin
        Writeln('Thread ID      '+inttohex(TThreadEntry.th32ThreadID,8));
        Writeln('base priority  '+inttostr(TThreadEntry.tpBasePri));
        Writeln('');
      end;

      NextProc := Thread32Next(SnapProcHandle, TThreadEntry);//get the Next Thread
    end;
  finally
    CloseHandle(SnapProcHandle);//Close the Handle
  end;
end;

begin
  { TODO -oUser -cConsole Main : Insert code here }
  GettthreadsList(GetCurrentProcessId); //get the PID of the current application
  //GettthreadsList(5928);
  Readln;
end.
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • Don't forget that TThreadEntry.dwSize is **set** by Thread32First and Thread32Next, so you **should** check it before accessing other fields. Different version of Windows return different amounts valid of data. – Jesse Chisholm Apr 02 '14 at 17:22
6

You can use my TProcessInfo class:

var
  CurrentProcess : TProcessItem;
  Thread : TThreadItem;
begin
  CurrentProcess := ProcessInfo1.RunningProcesses.FindByID(GetCurrentProcessId);
  for Thread in CurrentProcess.Threads do
    Memo1.Lines.Add(Thread.ToString);
end;
vcldeveloper
  • 7,399
  • 2
  • 33
  • 39
  • You need a custom library for that, named **Process Info** – TPAKTOPA Dec 17 '13 at 14:02
  • The link is broken, the domain does not exist anymore. There is an [archived copy](http://web.archive.org/web/20121010001118/http://vcldeveloper.com/products/products-components/process-info) of the page from 2012, but the code download is missing. – Remy Lebeau Jul 27 '16 at 23:30
3

You can also have a look at http://blog.delphi-jedi.net/2008/03/19/how-to-get-the-threads-of-a-process/

K.Sandell
  • 1,369
  • 10
  • 19
2

You can access this information using WMI.
The WIN32_Process can give you all information about process executing on Machine. For each process you can give ThreadsCount, Handle,...

Another class, WIN32_Thread can give you detailled information about all Threads running on Machine. This class hace a property called ProcessId for search especific threads for 1 process (class WIN32_Process).

For test it you can execute this on CommandLine window:

// all processes    
WMIC PROCESS   
// information about Delphi32    
WMIC PROCESS WHERE Name="delphi32.exe"   
// some information about Delphi32    
WMIC PROCESS WHERE Name="delphi32.exe" GET Name,descrption,threadcount,Handle
(NOTE: The handle for delphi32.exe in my machine is **3680**)

Similar you can do with WIN32_Thread using the Handle of process.

Excuse.me for my bad english.

Regards.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
0

If they are your threads, then I would create an application global Thread Manager to register themselves with upon creation. Then you can properly monitor, pause and shutdown threads gracefully using your Thread Manager.

Darian Miller
  • 7,808
  • 3
  • 43
  • 62