Solved

problem with closing set of programmes ?

Posted on 2004-10-11
24
270 Views
Last Modified: 2010-04-05
Hi guys
I use winexec  to run another program2 by my program
and use killtask to close this program2
===============================
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;
=============================
but some programmes2 ( which I run them by my program)
run another programmes3 at the same time they(which I run them by my program) begin run .
======
- my program run program2
- program2 run programmes3
======
so killtask close only the program2 which I run .
and  programmes3 which run with this program2 still working.

so, how can I close all those programs(program2 ,programmes3) ?
0
Comment
Question by:peruzzi
  • 14
  • 9
24 Comments
 
LVL 6

Expert Comment

by:vadim_ti
ID: 12282352
if you are running all this program2 , program3 and so on, you can use some undocumented features of
CreateProcess and STARTUPINFO to sign processes you will want to kill in future

http://www.catch22.net/tuts/undoc01.asp
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12284238
Wouldn't you if you want to kill program3 when you kill program2 use:

killtask(program2.exe);
killtask(program3.exe);

Regards,

Hypoviax
0
 

Author Comment

by:peruzzi
ID: 12290336
Hi
vadim_ti ,I only run program2(program3 run by program2
without my kown)

Hypoviax , I don't know the exename of program3
so I can't close it by killtask

0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12292550
The parent PID of program3 will be program2.

First find the PID of the program 2:

function FindPID(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 :=
FProcessEntry32.th32ProcessID
ContinueLoop := Process32Next(FSnapshotHandle,
FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

Next do a search for a parentPID that matches FindPID(program2.exe)

procedure tform1.killprogram3 ;
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
 listitem:Tlistitem;
             begin
              //      result := 0;
                   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                   FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
                   ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);

 while integer(ContinueLoop) <> 0 do
 begin

 if FProcessEntry32.th32ParentProcessID=FindPID(program2.exe) then //if equal then terminate it
TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), FProcessEntry32.th32ProcessID, 0);
  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);

end;
 CloseHandle(FSnapshotHandle);
end;

regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12292559
NOTE:You may need to put a BEGIN and END; around the terminate process part in the above example
0
 

Author Comment

by:peruzzi
ID: 12296803
Ok Hypoviax
I will try it and hope it success

peruzzi
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12303260
Good luck. There may be some syntax errors so just fix those
0
 

Author Comment

by:peruzzi
ID: 12318463
sorry Hypoviax  it did not success

in another way I want close all running programmes which are running after program2 run( any program )
this will be more usefully for me

can you help?I hope you can

peruzzi
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12324606
Hmmm....

I may have made a mistake in my code.  I don't have time right now but i will in a  bit. But the parent processID  (FProcessEntry32.th32ParentProcessID)  of any app which equals the ProcessID of program 2 (FProcessEntry32.th32ProcessID) will have been created by program 2
Fiddle around with the code.

I'll help in a bit if you can wait


0
 

Author Comment

by:peruzzi
ID: 12326798
No problem
take your time to solve it

peruzzi
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12330190
I have exams on (see my profile) at the moment so i won't be able to give you a detailed post until when i have some good spare time. I still believe that the code i posted should work. Maybe where i had terminateprocess(...) replace with:

killtask(FProcessEntry32.szExeFile);

Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12331002
Ok here we are, i've tested it and it works. This is an example:

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

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;

function FindPID(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
  begin
    Result :=FProcessEntry32.th32ProcessID
  end;
ContinueLoop := Process32Next(FSnapshotHandle,
FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

procedure tform1.killspawnedapps ;
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 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
                                                            //Change below to the name of program2
 if FProcessEntry32.th32ParentProcessID=FindPID('Program2.exe') then //if equal then terminate it
 begin
 killtask(FProcessEntry32.szExeFile);
 end;
  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);

end;
 CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
killspawnedapps ; //The procedure to kill all programs created by program2
end;

procedure TForm1.FormCreate(Sender: TObject);
begin //Open Program2                Open whereever program2 is   :                                                        
shellexecute(handle,'Open',pchar(extractfilepath(application.exename)+'Program2.exe'),'','',sw_show);
end;

end.

Best Regards,

Hypoviax
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:peruzzi
ID: 12340467
Hi
Hypoviax , thanks a lot for your fantastic solution
it  works very well
the points are for you( you answered the question)............. but I well increase it up to 200 points if you told me:

how can I close all running programmes which are running after the step of running program2 ?
for example:
(close all running programmes which were launched after specified time)

all running programmes may be not run by program2

this will solve my problem exactly as I want ....

peruzzi ...............
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12342558
I don't completely understand.

Do you want all programs to be closed that have been opened by program2 after a certain  time and allow others that have been opened prior to this time to remain?

I may know how to do this but i just need the question clarified a bit more

Regards,

Hypoviax
0
 

Author Comment

by:peruzzi
ID: 12342645
I want all programs to be closed that have been opened by program2 and by another program and by me in a direct way(means: all programmes which run after a certain time with no care about who run them) after a certain  time and allow others that have been opened prior to this time to remain

that what I want ,I hope it is clear now .

peruzzi........waiting your answer
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12342653
Or do you mean

Close all programs opened after a certain time regardless of whether they were opened by program2?

If this is the case i can do this

Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12342662
Ok i understand

0
 

Author Comment

by:peruzzi
ID: 12342694
that is exactly what I want
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12342735
procedure tform1.findprocesses ;
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
 listitem:Tlistitem;
             begin
              //      result := 0;
                   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                   FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
                   ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);

 while integer(ContinueLoop) <> 0 do
 begin
       ListItem :=      listview1.Items.Add; //add items
  ListItem.Caption := FProcessEntry32.szExeFile;
listitem.SubItems.Add(now)  ; //record time
  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
 CloseHandle(FSnapshotHandle);
end;

procedure tform1.findupdatedprocesses ;
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
 listitem:Tlistitem;
             begin
              //      result := 0;
                   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                   FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
                   ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);

 while integer(ContinueLoop) <> 0 do
 begin
listviewtemp.items.clear;
       ListItem :=      listviewtemp.Items.Add; //add items
  ListItem.Caption := FProcessEntry32.szExeFile;
listitem.SubItems.Add(datetimetostr(now))  ;//record time
if listviewtemp.items.count<>listview1.items.count then //if a new process comes in
begin
if strtodatetime(listviewtemp.items.item[listviewtemp.items.count-2].subitems[0])>strtodatetime(editsettime.text) then
begin
  killtask(listviewtemp.items.item[listviewtemp.items.count-2].caption);
end;

  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
 CloseHandle(FSnapshotHandle);
end;


This won't work but it is where i'm trying to head towards. I have exams on so am busy, i will have time around my lunch time ( 5 hrs from now)

Regards,

Hypoviax
0
 
LVL 5

Accepted Solution

by:
Hypoviax earned 200 total points
ID: 12344220
OK try this. It worked for me but im not sure how it will work if you set the time backwards prior to the creation of the program, other than that i think it will do what you want:

With this code you need to set a date as well as a time in the format : 19/10/2004 1:24:13 PM

If you want just the time use a different time function instead of "now"

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls,Tlhelp32, ExtCtrls, StdCtrls;

type
  TProcessSet = array[0..1000] of string;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
  ProcessStr:TProcessSet;
    procedure findprocesses ;
     procedure find_new_processes_created_after_time ;

  end;


var
  Form1: TForm1;



implementation

{$R *.dfm}

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;

procedure tform1.findprocesses ;  //create a snapshot of the running processes
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
 listitem:Tlistitem;
 X:integer;
           begin
            //     result := 0;
                FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
                ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);
        X:=-1;  //reset
 while integer(ContinueLoop) <> 0 do
 begin
 inc(x); //increment x
      processstr[x]:=FProcessEntry32.szExeFile; //add list to an array
  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
 CloseHandle(FSnapshotHandle);
end;

procedure tform1.find_new_processes_created_after_time ;
const
 PROCESS_TERMINATE=$0001;
 var
 ContinueLoop: BOOLEAN;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
 X,count:integer;
           begin
                FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
                ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);
               x:=-1;  //reset
               count:=x;   //reset
 while integer(ContinueLoop) <> 0 do
 begin
    inc(x); //increment x
      try
          if FProcessEntry32.szExeFile<>processstr[x] then
            begin
                inc(count)  //doesnt equal item then increment count
             end;
     except
      end;
        if count>-1 then  //it is a new process if >=0
          begin
              if now>strtodatetime(edit1.text) then  //if it is newer than time
                  begin
                    killtask(FProcessEntry32.szExeFile) ;      //kill it
                    // or use this if you only want to kill that specific one. If there are two notepad.exes for
                    //example they would both be closed with killtask whereas this wont:
                    //  TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),FProcessEntry32.th32ProcessID), 0))

                  end;
          end;
  ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);

  end;

 CloseHandle(FSnapshotHandle);
 //sleep(300);   //Updating list may need work if the current code doesn't do what you would like
 //findprocesses   ;   //get a list again
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
findprocesses   ;   //get a list
edit1.Text:=datetimetostr(now);   //set the time you want here
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
find_new_processes_created_after_time; //you should put this in a timer
end;

end.

Regards,

Hypoviax
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12352496
One thing i might add:

When a new process is opened and the time period is not up then you need to add it to the "before time  is up" list

where i have :

if now>strtodatetime(edit1.text) then  //if it is newer than time
                  begin
                    killtask(FProcessEntry32.szExeFile) ;      //kill it
                    // or use this if you only want to kill that specific one. If there are two notepad.exes for
                    //example they would both be closed with killtask whereas this wont:
                    //  TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),FProcessEntry32.th32ProcessID), 0))

                  end;

maybe have:

if now>strtodatetime(edit1.text) then  //if it is newer than time
                  begin
                    killtask(FProcessEntry32.szExeFile) ;      //kill it
                    // or use this if you only want to kill that specific one. If there are two notepad.exes for
                    //example they would both be closed with killtask whereas this wont:
                    //  TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),FProcessEntry32.th32ProcessID), 0))

                  end
                  else //ADDITION HERE
                       begin
                            processstr[x+1]:=FProcessEntry32.szExeFile; //Add to list
                       end;

However, try the original code first, it may work how you want but if you find the update 'bug' interferes with what you want try replacing the section with above coce

Regards again,

Hypoviax
0
 

Author Comment

by:peruzzi
ID: 12352732
ok,Hypoviax
I will try it

thanks
0
 

Author Comment

by:peruzzi
ID: 12384545
Hi
Hypoviax , Thanks a lot for this perfect work
It is realy perfect
you worth 200 points and more

thanks again

peruzzi
0
 
LVL 5

Expert Comment

by:Hypoviax
ID: 12386194
I am glad i could help. If you have any other problems associated with it post it here. I'll be able to help more around early november

Thanks,

Hypoviax
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

706 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

19 Experts available now in Live!

Get 1:1 Help Now