Solved

Killing Exes running from a delphi application

Posted on 2002-04-18
49
735 Views
Last Modified: 2010-04-04
Hi there
  Can You kill Exes from delphi? Like Microsoft word or internet explorer or games running like Half life, red alert etc.

If so how do you do this?

thanks so much !!!!!
0
Comment
Question by:allio
49 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6950125
yes, multiple possibilities
0
 
LVL 17

Expert Comment

by:geobul
ID: 6950129
Hi,

procedure TForm1.Button2Click(Sender: TObject);
var
 H : HWND;
begin
 H := FindWindow('notepad', nil);
 if IsWindow(H) then
   PostMessage(H, WM_CLOSE, 0, 0);
end;

Regards, Geo

0
 

Author Comment

by:allio
ID: 6950143
what if it does not have a window? but the exe is still running in the windows processes? how can you kill it?
0
 

Author Comment

by:allio
ID: 6950151
what if it does not have a window? but the exe is still running in the windows processes? how can you kill it?
0
 
LVL 17

Expert Comment

by:geobul
ID: 6950163
for IE: H := FindWindow('IEFrame', nil);
for MSWord: H := FindWindow('OpusApp', nil);
0
 
LVL 17

Assisted Solution

by:geobul
geobul earned 100 total points
ID: 6950173
You have to know Process ID (PID) at least to do that:

procedure TForm1.Button1Click(Sender: TObject);
var
  h: THandle;
  PID: DWORD;
begin
  try
    PID := StrToInt(Edit1.Text);
    h := OpenProcess(PROCESS_TERMINATE, false, PID);
    try
      if h <> 0 then TerminateProcess(h, 0);
    finally
      CloseHandle(h);
    end;
  except
    ShowMessage('Error');
  end;
end;

Regards, Geo
0
 

Author Comment

by:allio
ID: 6950206
how do you get the PID?
0
 

Author Comment

by:allio
ID: 6950213
how do you get the PID?
0
 
LVL 17

Expert Comment

by:geobul
ID: 6950234
What do you know about the app you are about to kill? What Windows versions should the code work on?
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6950240
look at www.madshi.net
there is all what you need

or wait until madshi joins this q
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 6950473
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.DFM}


var s:Tstringlist;


procedure TForm1.Button1Click(Sender: TObject);


function EnumWindowsProc(hwnd : HWND ;lParam : longint):boolean;stdcall;
var
  wn : array[0..255] of char;
  pid: THandle;
  w : string;
begin
  if hwnd <> 0 then
  begin
    GetWindowThreadProcessId(hwnd, @pid);
    // filter out if this is our application window
    // and all child windows
    if {(pid <> GetCurrentProcessId) and }(GetParent(hwnd)= 0) then
    begin
      // get the caption
      // or use the commented IF to get application names
      if GetWindowText(hwnd, wn,sizeof(wn)) <> 0 then
//    if GetModuleFileName(GetWindowLong(hwnd,GWL_HINSTANCE),wn,sizeof(wn)) <> 0 then
      begin{}
        w:= Format('%6d ',[pid])+StrPas(wn);
        S.Add(w);
      end;{}
   end;
    result := true;
  end else result := false;
end;

begin
  try
   S := TStringList.Create;
   S.Sorted := true;
   S.Duplicates := dupIgnore;
   ListBox1.Items.Clear;
   S.Clear;
   EnumWindows(@EnumWindowsProc,0);
   ListBox1.Items.AddStrings(S);
  finally
    S.Free;
  end;
end;

end.

now implement geobul's code.
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 6950489
just open a notepad..
now check for it's pid...
and kill... hahahaha (not really)

so who will get points? me or geobull or will allio be so nice and make a ask a new question with points for xxx?
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6950512
xxx := kretzschmar
:-)))
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6950689
I hate to pop anyone bubble here, but there is a slight snag with this question: To kill a process in Windows you need to get the pid (as already mentioned)... the snag come in actually getting that PID. In Windows 9x you have to use one API which doesn't work in NT/2000, and of course in NT/2000 you have to use another API. So, the first order of business HAS to be determing the operating system, then calling the appropriate function to enumerate the open processses and THEN killing the one you want. I have code for this archived OR you could just use my TEnumProcs component. You can get a demo application using it from my site:

http://www.drdelphi.com/delphi/right/comp.html


Good luck!!
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 6950804
really I didn't know could you elaborate since:

EnumWindows

Requirements
  Windows NT/2000/XP: Included in Windows NT 3.1 and later.
  Windows 95/98/Me: Included in Windows 95 and later.

source:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/windows_9v6r.asp
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6950887
The EnumWindows function enumerates all top-level windows on the screen by passing the handle of each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

This does nothing for windowsless (console) applications, nor does it give you the ProcessId. It'll only give you the handles for the WINDOWS that are open.

Hope this clears it up for you.


DrDelphi
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6950908
just to repost

look at www.madshi.net
there is all what you need

enumerates processes,
is win-version independent
0
 
LVL 7

Assisted Solution

by:God_Ares
God_Ares earned 100 total points
ID: 6950926
well allio that should round it up for you. you should be able to create what you want,

i'm going to check this api thing...
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6951430
Give me your address to send you a sample project that return a list of all running processes and give you the oportunity to close the wished applications.

Regards,
Nick
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6951438
Give me your address to send you a sample project that return a list of all running processes and give you the oportunity to close the wished applications.

Regards,
Nick
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6951439
Give me your address to send you a sample project that return a list of all running processes and give you the oportunity to close the wished applications.

Regards,
Nick
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6951480
Ginsonic,
  You can get that from my site... see above.

Good luck!!
0
 
LVL 4

Expert Comment

by:nestorua
ID: 6951751
HI,
Use the following (seems it is not mentioned yet):
CreateToolhelp32Snapshot,
Process32First,
Process32Next,
OpenProcess,
TerminateProcess.
Sincerely,
Nestorua.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6952658
DrDelphi , I see that your component isn't freeware .
And my sample project don't use any component to do this job .
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 9

Expert Comment

by:ginsonic
ID: 6952661
I remember that in past I answered here at Ex-Ex to a similar question and the asker was happy with my solution .
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6952687
a very old sample from my paq,
works only for win9x-versions,
(not tested for me,xp, but works not for nt, 2000)
it is not exact what you need

--- paste begin
here is a sample which stores processes with windows in a treeview
the windowhandle is stored in the data-option


     unit enumw2_u;

     interface

     uses
       Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
       StdCtrls, tlhelp32, ComCtrls;

     type
       TForm1 = class(TForm)
         Button1: TButton;
         TreeView1: TTreeView;
         Edit1: TEdit;
         procedure Button1Click(Sender: TObject);
         procedure TreeView1Click(Sender: TObject);
         procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
       private
         Procedure GetThreads(ProcessID : DWord);
         Procedure GetProcesslist;
         { Private-Deklarationen }
       public
         { Public-Deklarationen }
       end;

     var
       Form1: TForm1;

     implementation

     {$R *.DFM}

     Var
       WNode2: TTreeNode = Nil; {intern Global defined for multiple use}
       WNode : TTreeNode = Nil; {intern Global defined for multiple use}
       WName : Array[0..100] of char;
       TheWinHandle : THandle = 0; {intern Global defined for intern global Access}

     Function TWCallBack(H : THandle; V : Longint) : longBool; stdcall;
     begin
       if GetParent(H) = 0 then
       begin
         GetwindowText(H,@WName[0],100);
         WNode2 := Form1.TreeView1.Items.AddChild(WNode,StrPas(@WName[0]));
         WNode2.Data := Ptr(H); {Store the Handle in the DataOption}
       end;
       Result := True;
     end;

     Procedure TForm1.GetThreads(ProcessID : DWord);
     var
       ThreadEntry32 : TThreadEntry32; {Defined in TlHelp32}
       TLHandle : THandle;
     begin
       TLHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
       if Thread32First(TLHandle,ThreadEntry32) then
       begin
         if ThreadEntry32.th32OwnerProcessID = ProcessID then
           EnumThreadWindows(ThreadEntry32.th32ThreadID,@TWCallBack,0);
         while Thread32Next(TLHandle,ThreadEntry32) do
           if ThreadEntry32.th32OwnerProcessID = ProcessID then
             EnumThreadWindows(ThreadEntry32.th32ThreadID,@TWCallBack,0);
       end;
       CloseHandle(TLHandle);
     end;

     Procedure TForm1.GetProcesslist;
     var
       PLHandle : Thandle;
       ProcessEntry32 : TProcessEntry32; {Defined in TlHelp32}
     begin
       PLHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
       if Process32First(PLHandle,ProcessEntry32) then
       begin
         Wnode := TreeView1.Items.Add(Nil,strPas(@ProcessEntry32.szExeFile[0]));
         GetThreads(ProcessEntry32.th32ProcessID);
         while Process32Next(PLHandle,ProcessEntry32) do
         begin
           Wnode := TreeView1.Items.Add(Nil,strPas(@ProcessEntry32.szExeFile[0]));
           GetThreads(ProcessEntry32.th32ProcessID);
         end;
       end;
       CloseHandle(PLHandle);
     end;

     Procedure CleanUpTree(Nodes : TTreeNodes);
     begin
       {CleanUp Windows without Text (most Controls)}
       WNode := Nodes.GetFirstNode;
       While WNode <> Nil do
       begin
         If WNode.Text = '' then
         begin
           WNode2 := WNode.Getnext;
           WNode.Delete;
           WNode := WNode2;
         end
         else
           WNode := WNode.GetNext;
       end;
       {CleanUp Processes with no windows}
       WNode := Nodes.GetFirstNode;
       While WNode <> Nil do
       begin
         If (WNode.Parent = Nil) and (WNode.GetFirstChild = Nil) then
         begin
           WNode2 := WNode.Getnext;
           WNode.Delete;
           WNode := WNode2;
         end
         else
           WNode := WNode.GetNext;
       end;
     end;

     procedure TForm1.Button1Click(Sender: TObject);
     begin
       Treeview1.Items.Clear;
       GetProcessList;
       CleanUpTree(TreeView1.Items);
     end;

     procedure TForm1.TreeView1Click(Sender: TObject);
     begin
       If Treeview1.selected.Level = 1 then //Level 1 entrys Only
       begin
         TheWinHandle := THandle(Treeview1.selected.Data); //Get the Handle from the DataOption
         // Do Something with the Handle, must not be in this Procedure
         edit1.text := IntToStr(TheWinHandle);
       end;
     end;

     procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
     begin
       TreeView1Click(Self);
     end;

     end.
---paste end

meikl ;-)
0
 

Author Comment

by:allio
ID: 6952697
Can I make a program that works on all OS? not just on 98 or NT
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6952704
just to repost

look at www.madshi.net
there is all what you need

enumerates processes,
is win-version independent
;-)
0
 

Author Comment

by:allio
ID: 6952720
Can I make a program that works on all OS? not just on 98 or NT
0
 

Author Comment

by:allio
ID: 6952753
kretzschmar ,
  where in madshi.net can i find the answer?
  thanks
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6952774
allio , I see that you aren't interested to have a full source code project for this job :(
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 6952781
look at the madKernel, there
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6956799
Hi guys,

thanx a lot, meikl, for (repeatedly) pointing to my homepage...  :-))

Yes, with madKernel you can do things like e.g.

  // this is the hardest close, like terminating with task manager
  Process('explorer.exe').Terminate;

  // this is a hard close, but a bit friendlier than Terminate
  Process('notepad.exe').Quit;

  // this is like clicking in [X] of the main window
  Process('calc.exe').Close;

and much more. Everything works in every OS, of course. madKernel is free for non-commercial usage, but doesn't come with sources then.

Alternatively you can use my totally free unit "enumStuff" (with sources), which can enumerate processes in every OS. You have to do the killing part yourself, in that case. But it's not difficult, just calling OpenProcess and TerminateProcess (or EnumWindows + PostMessage(WM_CLOSE)).

www.madshi.net/enumStuff.zip

Hi Nestorua, your suggestion does not work in NT4.

Hi DrDelphi, just for my interest: Does your stuff need PsApi.dll?

Hi ginsonic, which method are you using for enumerating the processes? Does it work in NT, too? Does it work for window-less processes? Do you need PsApi.dll?

Regards, Madshi.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6957328
I see that you don't wish to make public your e-mail address .

So , get this demo from my site .
http://www.ginsonic.ro/demo.zip

When click the 'List' get the list of all running applications .

When click 'Terminate' finish the selected process .

When double click an item from list then you can get all infos about that process ( ID, filename, path .... ).
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6957401
Forgot to upload . Try now .
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6957521
Hi ginsonic, your demo doesn't work in NT4.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6958847
I tested only in Win98 and XP
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6958853
Yeah, win95, 98, ME, 2k and XP work fine, because they all support the toophelp functions. But NT4 never did and probably never will support the toophelp functions...
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6975826
This question is current, others below are not and need your attention.  ADMINISTRATION WILL BE CONTACTING YOU SHORTLY.  Moderators Computer101 or Netminder will return to finalize these if they are still open in 14 days.  Experts, please post closing recommendations before that time.

Below are your open questions as of today.  Questions which have been inactive for 21 days or longer are considered to be abandoned and for those, your options are:
1. Accept a Comment As Answer (use the button next to the Expert's name).
2. Close the question if the information was not useful to you, but may help others. You must tell the participants why you wish to do this, and allow for Expert response.  This choice will include a refund to you, and will move this question to our PAQ (Previously Asked Question) database.  If you found information outside this question thread, please add it.
3. Ask Community Support to help split points between participating experts, or just comment here with details and we'll respond with the process.
4. Delete the question (if it has no potential value for others).
   --> Post comments for expert of your intention to delete and why
   --> YOU CANNOT DELETE A QUESTION with comments; special handling by a Moderator is required.

For special handling needs, please post a zero point question in the link below and include the URL (question QID/link) that it regards with details.
http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
 
Please click this link for Help Desk, Guidelines/Member Agreement and the Question/Answer process.  http://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp

Click you Member Profile to view your question history and please keep them updated. If you are a KnowledgePro user, use the Power Search option to find them.  

Questions which are LOCKED with a Proposed Answer but do not help you, should be rejected with comments added.  When you grade the question less than an A, please comment as to why.  This helps all involved, as well as others who may access this item in the future.  PLEASE DO NOT AWARD POINTS TO ME.

To view your open questions, please click the following link(s) and keep them all current with updates.
http://www.experts-exchange.com/questions/Q.11410418.html
http://www.experts-exchange.com/questions/Q.20247100.html
http://www.experts-exchange.com/questions/Q.20290838.html
http://www.experts-exchange.com/questions/Q.20291273.html



*****  E X P E R T S    P L E A S E  ******  Leave your closing recommendations.
If you are interested in the cleanup effort, please click this link
http://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=commspt&qid=20274643
POINTS FOR EXPERTS awaiting comments are listed in the link below
http://www.experts-exchange.com/commspt/Q.20277028.html
 
Moderators will finalize this question if in @14 days Asker has not responded.  This will be moved to the PAQ (Previously Asked Questions) at zero points, deleted or awarded.
 
Thanks everyone.
Moondancer
Moderator @ Experts Exchange
0
 
LVL 1

Expert Comment

by:quantum2
ID: 7011841
This is a unit that I have used to do something very simillar. It is rock solid and works well.
=====================
INSTRUCTIONS FOR USE
=====================

1. Copy the ProcessViewer.pas file into a directory of your choice (recommend the directory of your project)
2. Include the Unit in your USES block.

Now you have access to the functions and properties.

Hint: The ProcessViewer only examines processes with a window handle!


Methods and functions
---------------------

METHOD GetProcessList:

      Simply call this function in your code and the ProcessViewer Unit fills the ProcessInfo array.
      You should ever use GetProcessList before you take your own action with processes.
      So you can be sure to have the newest image of the processes.

      The internal functions like kill-processes calls GetProcessList self, so you don't need this do.


FUNCTION IsFileActive(FileName: string): boolean

      This function checks, if the file "FileName" is executed.
      You can include the path and drive letter or not.
      The execution with path and drive letter is a little bit faster.
      It returns TRUE, if the file is executed and FALSE, if not.

      The function calls "GetProcessList" before it goes for checking so you don't need do this manually.

      Example:

            if IsFileActive('DELPHI32.EXE') then
            begin
                  ShowMessage('Delphi runs!');
            end;


FUNCTION KillProcessByFileName(FileName: string, KillAll: boolean): boolean

      Use this function when you want to terminate(kill) a process, when you know the name of the file.
      "FileName" is the file name of the process, that you want to kill.
      You can include the path and drive letter (i.e: c:\windows\cdplayer.exe) or not (i.e. cdplayer.exe).

      "KillAll" is a flag. When it is TRUE, ALL processes executed by the file will be terminated (a file
      can execute more than one process).
      When it is FALSE, only the first found process executed by the file will be killed.
      The order of the processes are managed by Windows, so you probably not know which process is
      exactly "your" process.

      The function returns TRUE, when it killed the process(es) successfully.
      The function returns FALSE, when the termination of all processes (KillAll=true) or one file
      (KillAll=false)      failed or the file are not executed at this time.

      The function calls "GetProcessList" before it goes for terminating so you don't need do this manually.

      Hint: On slower machines or on very busy systems it can be possible, that the return value are
      FALSE but the process is killed anyway after some milliseconds. In this case you should increase the value
      "SleepForReCheck" (see below in this file).

      Example:

            if KillProcessByFileName('CDPLAYER.EXE',true) then
            begin
                  ShowMessage('All instances of the Windows CD player are closed.');
            end;


FUNCTION KillProcessByPID(PID: DWord): boolean

      Use this function when you want to terminate(kill) a process,
      when you know the ProcessID of the process. It's seldom, but sometimes you need this function.

      It's also called internal from "KillProcessByFileName".

      "PID" is the ProcessID of the process, that you want to kill.

      The function calls "GetProcessList" before it goes for terminating so you don't need this manually.

      The function returns TRUE, when it killed the process successfully.
      The function returns FALSE, when the termination failed or the PID doesn't exist.

      Hint: On slower machines or at very busy systems it can be possible, that the return value are
      FALSE but the process is killed anyway. In this case you should increase the value
      "SleepForReCheck" (see below in this file).

      Example:

            if KillProcessByPID(3278354) then
            begin
                  ShowMessage('Process with PID '+IntToStr(3278354)+' are terminated.');
            end;




Properties
----------

This is the data structure of the ProcessInfo record:

type TProcessInfo=record
            FileName: string;
            Caption: string;
            Visible: boolean;
            Handle: DWord;
            PClass: string;
            ThreadID: DWord;
            PID: DWord;
end;

var ProcessInfo: array of TProcessInfo;

      When you call "GetProcessList" the array "ProcessInfo" will be filled with all informations
      about the running processes.

      Here are the details of the ProcessInfo structure:

      FileName:            The file that executed the process (with complete path)
      Caption:            Caption of the window (can be empty)
      Visible:             If TRUE, the window is visible
      Handle:             Internal handle of the window
      PClass:                  Internal class of the window
      ThreadID:            Internal ThreadID of the process
      PID:                        Internal ProcessID of the process (used for the kill-functions).


      Ok, this example lists all file names in a TStringList:

                  procedure ListAllFiles;
                  var
                        i: integer;
                        FileList: TStringList;
                  begin
                        FileList:=TStringList.Create;                                     //prepare the stringlist
                        GetProcessList;                                                                               //update the ProcessInfo Array
                        for i:=0 to Length(ProcessInfo)-1 do                   //walk through the ProcessInfo array
                        begin
                              FileList.Add(ProcessInfo[i].FileName);      //copy the filenames in the list
                        end;
                        .
                        .
                        .
                  end;

var
      DateiList,CaptionList,VisibleList,HandleList,ClassList,ThreadIdList,PIDList: TStringList;

      These lists are used internal by the ProcessViewer unit. They are published and can used in your code.

      So the previous example can make easier:

                  procedure ListAllFiles;
                  var
                        FileList: TStringList;
                  begin
                        FileList:=TStringList.Create;                                     //prepare the stringlist
                        GetProcessList;                                                                               //update the ProcessInfo Array
                        FileList:=DateiList;                      //copy the filelist
                        .
                        .
                        .
                  end;

            I recommend to use the ProcessInfo array and NOT the lists! When you use such created lists with
            simply a=b then a can changed when b change.

            Such programming is called "dirty code". Don't do this.

            The ProcessInfo array will be constant until you call another function of the unit.


const      SleepForReCheck;

      I use a constant "SleepForReCheck" to give the process killing functions time
      to finish the work (some processes needs more time to close all connections). The
      constant is used in a For-To-loop together with Application.ProcessMessages.

      The default value is 5000, this should be enough for the most processes. When you
      expect that your application runs on slower or busy machines then increase the value.

      Pay attention, some tools at the users controls processes (i.e. resources manager). They must recalculate
      their data between your terminate-commands. Considerate this!
      
      A good pre-check is, to open a executable more times (about 15-20 times) and try to close all with
      a KillProcessByFileName-Command. When it closes all without interrupt it is ok (on your machine).

      You can change this constant directly in the source code.




Finally
----------------
      When you don't know, what processes are and what you want with a processviewer, please don't use this unit.

      The terminating of processes is the hardest way to kick a program out of the memory. It's not the same like
      normal close with sending a WM_CLOSE message. It is like cut the powerline of a computer.

      Don't kill system processes. I'm not responsible for damages on your hardware or software!

      This Unit is freeware and I don't give support for this. Feel free to change some
      things and develope your own Unit from this.

====
Actual Unit Code

unit ProcessViewer;

interface

uses
      Windows, Dialogs, SysUtils, Classes, ShellAPI, TLHelp32, Forms;

const
      SleepForReCheck=5000;

type TProcessInfo=record
      FileName: string;
      Caption: string;
      Visible: boolean;
      Handle: DWord;
      PClass: string;
      ThreadID: DWord;
      PID: DWord;
end;


var
      DateiList,CaptionList,VisibleList,HandleList,ClassList,ThreadIdList,PIDList: TStringList;
      ProcessInfo: array of TProcessInfo;

function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): Bool; stdcall;
function KillProcessByPID(PID: DWord): boolean;
function KillProcessByFileName(FileName: string; KillAll: boolean): boolean;
procedure GetProcessList;
function GetFileNameFromHandle(Handle: hwnd):string;
function IsFileActive(FileName: String): boolean;

implementation

procedure GetProcessList;
var
      i,Laenge: integer;
begin
DateiList.Clear;
HandleList.Clear;
ClassList.Clear;
CaptionList.Clear;
VisibleList.Clear;
ThreadIdList.Clear;
PIDList.Clear;
EnumWindows(@EnumWindowsProc, 0);
Laenge:=DateiList.Count;
SetLength(ProcessInfo,Laenge);
for i:=0 to Laenge-1 do
begin
      DateiList[i]:=UpperCase(DateiList[i]);
      with ProcessInfo[i] do
      begin
            FileName:=DateiList[i];
            Caption:=CaptionList[i];
            Visible:=VisibleList[i]='1';
            Handle:=StrToInt64(HandleList[i]);
            PClass:=ClassList[i];
            ThreadID:=StrToInt64(ThreadIdList[i]);
            PID:=StrToInt64(PIDList[i]);
      end;
end;
end;

function IsFileActive(FileName: String): boolean;
var
      i: integer;
begin
result:=false;
if FileName='' then exit;
GetProcessList;
FileName:=UpperCase(ExtractFileName(FileName));
for i:=0 to Length(ProcessInfo)-1 do
begin
      if Pos(FileName,ProcessInfo[i].FileName)>0 then
      begin
            result:=true;
            break;
      end;
end;
end;

function GetFileNameFromHandle(Handle: hwnd):string;
var
      PID: DWord;
      aSnapShotHandle: THandle;
      ContinueLoop: Boolean;
      aProcessEntry32: TProcessEntry32;
begin
GetWindowThreadProcessID(Handle, @PID);
aSnapShotHandle := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
aProcessEntry32.dwSize := SizeOf(aProcessEntry32);
ContinueLoop := Process32First(aSnapShotHandle, aProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
      if aProcessEntry32.th32ProcessID = PID then
      begin
            result:=aProcessEntry32.szExeFile;
            break;
      end;
      ContinueLoop := Process32Next(aSnapShotHandle, aProcessEntry32);
end;
CloseHandle(aSnapShotHandle);
end;

function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): Bool;
var
      Capt,Cla: array[0..255] of char;
      Datei: string;
      ident: dword;
begin
GetWindowText(hWnd, Capt, 255);
GetClassName(hwnd,Cla,255);
ThreadIdList.Add(IntToStr(GetWindowThreadProcessId(hwnd,nil)));
Datei:=GetFileNameFromhandle(hwnd);
DateiList.Add(Datei);
HandleList.Add(IntToStr(HWnd));
if IsWindowVisible(HWnd) then VisibleList.Add('1') else VisibleList.Add('0');
ClassList.Add(Cla);
CaptionList.Add(Capt);
GetWindowThreadProcessId(StrToInt(HandleList[HandleList.Count-1]),@ident);
PIDList.Add(IntToStr(ident));
Result:=true;
end;

function KillProcessByPID(PID : DWord): boolean;
var
      myhandle : THandle;
      i: integer;
begin
myhandle := OpenProcess(PROCESS_TERMINATE, False, PID);
TerminateProcess(myhandle, 0);
for i:=0 to SleepForReCheck do Application.ProcessMessages; //Genug Zeit geben
GetProcessList;
Result:=PIDList.IndexOf(IntToStr(PID))=-1;
end;

function KillProcessByFileName(FileName: string; KillAll: boolean): boolean;
var
      i: integer;
      FileFound: boolean;
begin
result:=false;
if FileName='' then exit;
FileName:=UpperCase(ExtractFileName(FileName));
result:=true;
GetProcessList;
if KillAll then
begin
      //Kill all
      FileFound:=false;
      repeat
            GetProcessList;
            FileFound:=false;
            for i:=0 to DateiList.Count-1 do
            begin
                  if Pos(Filename,DateiList[i])>0 then
                  begin
                        FileFound:=true;
                        break;
                  end;
            end;
            if i<DateiList.Count then
            begin
                  if not KillProcessByPID(StrToInt64(PIDList[i])) then
                  begin
                        result:=false;
                        exit;
                  end;
            end;
      until not FileFound;
end else
begin
      //Kill one
      for i:=0 to DateiList.Count-1 do
      begin
            if Pos(Filename,DateiList[i])>0 then break;
      end;
      if i<DateiList.Count then
      begin
            if not KillProcessByPID(StrToInt64(PIDList[i])) then
            begin
                  result:=false;
                  exit;
            end;
      end;
end;
end;

initialization
DateiList:=TStringList.Create;
HandleList:=TStringList.Create;
ClassList:=TStringList.Create;
CaptionList:=TStringList.Create;
VisibleList:=TStringList.Create;
ThreadIdList:=TStringList.Create;
PIDList:=TStringList.Create;

finalization
DateiList.Free;
HandleList.Free;
ClassList.Free;
CaptionList.Free;
VisibleList.Free;
ThreadIdList.Free;
PIDList.Free;

end.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7011871
quantum2, this code doesn't work in NT4.
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 7011887
at the risk of beating a dead horse, my component DOES work in NT4,Win2k and 98...


0
 
LVL 20

Expert Comment

by:Madshi
ID: 7011892
:-)
0
 
LVL 1

Expert Comment

by:quantum2
ID: 7012967
Can you be more specific than that...? I am sure it compiles and runs, did you place the kill routines in a try and except and see where it is failing...?

The code works great in XP, 2000, 2000 AS, ME, 98 and 95. I dont have an NT 4 box laying around to test on here. I can try at my other office.

Give me some more details and I will see what I can do. This is really kinda basic. Also, there have been several good posts both with code and components, certainly someone has gotten in the ball park with an answer by now.

Q2
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7013040
Q2, the code you posted is built on the toolhelp functions. The toolhelp functions are available in all the OSs you listed, but they are not and will never be available in NT4. So your code can't work in NT4. There were two NT4-compatible solutions posted here already, one is DrDelphi's stuff, one is my stuff.

Regards, Madshi.
0
 
LVL 4

Expert Comment

by:nestorua
ID: 7014570
HI, Madshi,
I know about toolhelp functions and NT4.
Simply let the inquirer, allio, join two of the proposed solutions which cover all the possibilities.
Sincerely,
Nestorua.
0
 
LVL 1

Expert Comment

by:Pandora
ID: 8054591
ages ago I asked a very similar question, & as a result used processviewer.pas (thanks Dr Delphi) for a long time which worked really really well... until I ran an app on (wait for it Madshi!)...NT4..and it bombed, and it has been a bit of a nightmare...so its quite funny reading this as I really wish I'd seen it earlier.  I have to say I'm off to Madshi's site right now to get the mad suite...& do you know, I think I'm even gonna pay for it!
Best wishes P :)
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9003512
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Split between geobul and kretzschmar and God_Ares

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 

Expert Comment

by:Rebelss
ID: 27594436

try killtask('utilman.exe') except end;
function KillTask(ExeFileName: string): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(
OpenProcess(PROCESS_TERMINATE,
BOOL(0),
FProcessEntry32.th32ProcessID),
0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

Open in new window

0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now