Link to home
Start Free TrialLog in
Avatar of Blood_Line
Blood_Line

asked on

Working with listing running Processes

make it clean, make it neat and more points will be awarded.

to make it fairely strait forward (the CTRL+ALT+DEL) in windows brings up the all to familiar list of running programs I want to for the most part recreate this.

the first thing I need to do is to be able to list the programs that are running. Once I have the process name I can close the app. can some one give me a nice clean way to get a list of all running applications.

by the way this is for a Win NT machine so unregistered proccesses shouldn't be a problem like 9x if you know of a possible conflict comments are more than welcome.

Thank you // Bloodline
Avatar of Madshi
Madshi

Hi Bloodline,

if you have D4-6 and want to have it easy, you can use my package "madKernel" (free for non-commercial usage). With it you can do things like this:

// show all running processes:
with Processes do
  for i := 0 to ItemCount - 1 do
    ShowMessage(Items[i1].ExeFile);

// soft close first found notepad instance, as if user clicks [X]
Process('notepad.exe').Close;

// close all notepad instances without saving (Quit doesn't work with all programs correctly)
Processes('notepad.exe').Quit;

// hard stop explorer like NT task manager does, not very clean, but works (almost) always
Process('explorer.exe').Terminate;

// terminate everything including ourselves...   :-)
Processes.Terminate;

Of course everything works with both win9x and NT family.

I've also something to offer, which is free for commercial usage, too, and also contains the sources, but it's not that comfortable and mighty as "madKernel" is:

http://www.madshi.net/enumStuff.zip

With it you can also enumerate all processes in all systems, but you have to care about closing yourself. You can use PostMessage(processMainWindow, WM_CLOSE, 0, 0), PostThreadMessage(processMainThreadID, WM_QUIT, 0, 0) or TerminateProcess(processHandle, 0) to achieve similar results to the examples above.

Regards, Madshi.

www.madshi.net
Avatar of Blood_Line

ASKER

let me have a day or so to look everything over and see if I can pick out what I need I prefer strait code makes it easier to apply to other programs later down the road and makes it easier to modify to meet my needs specificaly. but I am checking int the unumstuff for now. until then
thank you for your help and other comments are still welcome.

//BloodLine
after looking over enum I am almost possitive that I should be able to pull what I need I only require a little help in converting a few results into information that I am familiar with so that I may view the processes in a list. are you willing to do this?
If it is really only "a little help", then no problem...   :-)   Have not too much time, though...

Regards, Madshi.
ASKER CERTIFIED SOLUTION
Avatar of smurff
smurff

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Smurff!

>> Ive got this if it helps

Unfortunately it doesn't help much, because NT4 doesn't support the toolhelp functions...   :-(

>> Madshis components are very good though!

Thanx...   :-)

Regards, Madshi.
Madshi,

>Unfortunately it doesn't help much, because NT4 doesn't support the toolhelp functions...   :-(

Thats why theres the two procedures, I have tested it on NT and it works for me.

Regards
Smurff
Madshi,
On reflection, you solution is much easier e.g.

>if you have D4-6 and want to have it easy, you can use my >package "madKernel" (free for non-commercial
>usage). With it you can do things like this:

>// show all running processes:
>with Processes do
> for i := 0 to ItemCount - 1 do
>   ShowMessage(Items[i1].ExeFile);

So dont think Im competing for points or anything, I just thought that BloodLine might learn something from seeing some code to play with.....Ive found the best way to learn is playing around. My 2 pence worth :)

Regards
Smurff
Ooops, I missed the NT part of your code, I'm sorry...

However: Your code needs psApi.dll to run under NT4 and psApi.dll is not included in every NT installation. So you have to distribute this dll with your application (that is allowed) if you're using that code. My code (both enumStuff and madKernel) works without needing that psApi.dll.

Regards, Madshi.
thank you both I am attempting to empliment the code the best I can and smurff I appreaciate the code to me it seems a little more user friendly to apply in the future. and it also seems tailored more towards what I actualy need there for I am most likely going to award you the points but I need to examine witch works with my problem most I believe that I would like to give you both points for your help I have points to blow god bless the accumulating points thing and I usualy only use exchange for maybe one major project a year. so this is what I will do one of you may have the points listed and I will set another question out for the other I will allow you to decide who shall get wich  either way you will both make out with 300 points.

I will also soon be posting another question specificaly on killing applications and will be giving more points for that also so if you want easy points keep the eye out for it. does this sound like an agreable arangement?


I am how ever having a problem with getting applications to die do you to think this may be the way I am doing it and the code works well or should I look for a better method of closing applications?
>> does this sound like an agreable arangement?

Absolutely...  :-)

Please note, that with Smurff's code you need to distribute psApi.dll with your application. Just wanted to make that clear, in case you missed it...

>> I am how ever having a problem with getting applications to die

There are several ways of killing apps. I've explained that in my first comment (see the last paragraph). In fact the killing code in Smurff's code is not a good one. SendMessage(WM_CLOSE) fails *very* often. Just exchange "SendMessage" with "PostMessage", then it will run a lot better. Besides from the WM_CLOSE killing there are at least 2 other ways, see my first comment.

Regards, Madshi.
Madshi,

>Please note, that with Smurff's code you need to >distribute psApi.dll with your application. Just wanted
>to make that clear, in case you missed it...

I havent specifically installed the .dll and I have it. Ive installed Service pack 6, IE 5.5, Office2k, Delphi5Ent, PSP7... I know its not a default installation dll so I can assume that its a popular dll.
It's documentation resides under "Windows Base Services",
"Windows NT Features", "Process Status Helper" and every PC in my company seems to have it....The dll itself is only 18k so if you did need to distribute it then its not that much of an issue (i think anyway). I am still saying your components are very good though.

Bloodline,
Wow. thanks I wasnt expecting points. How are you trying to kill it? was it the procedure I put? if so then I think theres probably a better way. I didnt know about the PostMessage like what Madshi said so sorry about that.
I also noticed that the proc. I showed you closes apps by the caption name in the titlebar, but the list produces the .exe name. The EnumProcesses does produce an array or process Id`s. Its probably better killing them by that. I`ll have a look for you(or does Madshi already know?)

Thanks anyway, Kind regards
Smurff

>> I havent specifically installed the .dll and I have it.

If I remember right it's included in SP6 or something like that. But if you don't want your application to require SP6, you would nevertheless have to distribute psApi.dll with your app. No big thing, of course. Just worth a mention...

>> I also noticed that the proc. I showed you closes apps by the caption name in the titlebar, but the list produces the .exe name. The EnumProcesses does produce an array or process Id`s. Its probably better killing them by that. I`ll have a look for you(or does Madshi already know?)

As I've stated in my first comment, there are (at least) 3 ways of closing an application. When only having the processID of the to-be-stopped process you can without much problems use OpenProcess + TerminateProcess. Getting the main window of a processID (for the WM_CLOSE solution) is a bit more work, you need to call EnumWindows and then GetWindowThreadProcessID for each enumerated window. The biggest problem is the PostThreadMessage solution, since psApi.dll can't enumerate threads. But I suggest moving the closing question to Bloodline's new question, which is already online...

Regards, Madshi.
this was a rather good answer to my question it was answered in close accordance to my needs and specifications in the question.

//BloodLine
Madshi,
Thanks for the comments. I havent had time today to look at the closing of the apps. Its something worth playing with for Bloodline (and myself) cos in my eyes thats the only way to learn. I didnt know about Bloodlines other question. Again, Ive learned from you and Ive took your comments on board. thanks

Bloodline,
Many thanks for the points, Im not really in it for the points, I just come here to learn new things and help out, but its always nice to know when your help and time is appreciated. Good luck with your codeing.
Regards
Smurff
BloodLine,

Looking into this further Ive also found this. I dont know where it came from, it was just in my "Delphi Crap to sort" directory :) It might help you learn more about the whole "process" thing. anyway thought it might help.
Regards
Smurff

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls,TlHelp32;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  EnumWindowsProc = function (Hwnd: THandle;Param: Pointer): Boolean; stdcall;

function GetWindowExeName(Handle: THandle): String;
var
  PE: TProcessEntry32;
  Snap: THandle;
  ProcessId: cardinal;
begin
  GetWindowThreadProcessId(Handle,@ProcessId);
  Snap:= CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> 0 then begin
    if Process32First(Snap, PE) then
      if PE.th32ProcessID = ProcessId then
        Result:= String(PE.szExeFile)
      else while Process32Next(Snap, PE) do
        if PE.th32ProcessID = ProcessId then begin
          Result:= String(PE.szExeFile);
          break;
        end;
    CloseHandle(Snap);
  end;
end;

function GetTitle (Hwnd: THandle; Param: Pointer): Boolean; stdcall;
 var
  Text,TempString: string;
begin
  If (GetWindowLong(Hwnd,GWL_HWNDPARENT)=0) and (IsWindowVisible(Hwnd) or IsIconic(Hwnd))then
  begin
TempString := GetWindowExeName(Hwnd);
  SetLength (Text, 100);
  GetWindowText (Hwnd, PChar (Text), 100);
  Form1.ListBox1.Items.Add (IntToStr (Hwnd) + ' : '  + TempString + ' : ' +text);
  Result := True;
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  EWProc: EnumWindowsProc;
begin
  ListBox1.Items.Clear;
  EWProc := GetTitle;
  EnumWindows (@EWProc, 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
wnd :Hwnd;
temp :string;
EWProc: EnumWindowsProc;
ClickedOK :  boolean;
begin
clickedOK := InputQuery('Which Process do U wanna Kill','Process Number',temp);
if ClickedOK then
begin
Wnd := hwnd(strToInt(temp));
PostMessage(Wnd,WM_SYSCOMMAND,SC_CLOSE, 0);
  sleep(100);
  ListBox1.Items.Clear;
  EWProc := GetTitle;
  EnumWindows (@EWProc, 0);
end;
end;
end.
thx I will be shure to take a look at it some time this week