Newsgroup: it.comp.lang.delphi
Titolo: Killare un programma

Ho la necessità di creare una routine che alla presenza di un file di testo 
con scritto dentro "killme" nella dir kill mi arresti un programma in 
esecuzione.
Sinceramente nn so da dove iniziare....... 


Attraverso "Google Groups", ho trovato una discussione che reca quasi lo 
stesso titolo del tuo messaggio... ;-)
Ecco il link:
http://makeashorterlink.com/?N187567F9
Credo che come punto di partenza possa andare...
Ciao! :-)
-- 
Marco «Alka» Breveglieri
  ABLS Team S.n.c. - Software & Web
  Via De Gasperi, 14
  42019 Scandiano (Reggio Emilia)
 
http://www.abls.it

Ciao, guarda un po' qua.
Io uso questo sistema (per la documentazione guarda i commenti)
procedure Termina_Applicazione(NomeApplicazione : String);
var
   t,a   : thandle;
   i     : tagPROCESSENTRY32;
   error : integer;
begin
   // creo uno snapshot del sistema
   // Una descrizione delle procedure
CreateToolhelp32Snapshot,process32first,
   // process32next si trova nel file di help "95guide.hlp" nella cartella:
   // C:\Programmi\File comuni\Borland Shared\MSHelp
   // includere TLHELP32 nelle USES!
   t := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,GetCurrentProcessId);
   i.dwSize := sizeof(i); // !importantissimo!
   process32first(t,i);
   while getlasterror<>ERROR_NO_MORE_FILES do
   begin
      if not(pos(NomeApplicazione, UpperCase(i.szExeFile)) = 0) then
      begin
         // apro il processo con tutti i privilegi
         a:=OpenProcess(PROCESS_ALL_ACCESS,true,i.th32ProcessID);
         error:=0;
         // killo il processo
         Terminateprocess(a,error);
      end;
      process32next(t,i);
   end;
   closehandle(t);  // chiudo l'handle (importante!)
end;

 ha scritto nel messaggio 
news:y3rtd.477488$35.20...@news4.tin.it...


Ti ringrazio x avermi risposto, ma nn ho capito come dirgli il programma 
specifico da killare, in quanto il pid cambia.
"Marco Breveglieri" <ma...@NOSPAM-abls.it> ha scritto nel messaggio 
news:68ptd.38544$B06....@news.edisontel.com...


 utilizzo D6
anche io ;)

 procedure Termina_Applicazione(NomeApplicazione : String);
.. Provvidenziale. Da un po mi dannavo per generarmi l'elenco dei
processi.
Favoloso !!! Ti ringrazio
Giovanni Caramia
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 CreateToolhelp32Snapshot,process32first,
[...]
Indubbiamente quello che ti ha suggerito David è il miglior sistema, ovvero 
le ToolHelp.
Bisogna però fare attenzione che queste, a causa di una certa ostinazione di 
microsoft nel voler portare avanti le PSAPI, non sono presenti in tutti i 
sistemi operativi.
Se dovessi eseguire questo codice su una macchina NT (o forse anche su un 
Win2K versione base) otterresti degli errori in quanto quelle funzioni non 
esistono in quel sistema operativo.
Saluti
--
- Carlo - 

Ciao Carlo! :)
Hai ragione ricordavo qualcosa del genere, cmq confermo che su Win2k pro
funziona correttamente (quasi tutti i client della mia applicazione che
sfruttano quella funzione sono Win2k)
Da MSDN, per CreateToolhelp32Snapshot, su macchine client :
Requires Windows XP, Windows 2000 Professional, Windows Me, Windows 98, or
Windows 95.
PS:Carlo, ci becchiamo presto su Messenger ;)

Si effettivamente avevo omesso ^^'. Cmq mi genera un altro errore
CreateToolhelp32Snapshot, Process32First;
[Error] Unit1.pas(34): Not enough actual parameters
Sinceramente qua brancolo nel buio....... :-\

Stai usando la funzione che ti ho dato così com'era?
Se sì, su che righe ti dà errore?
Altrimenti posta il codice e le unit incluse nella clausola uses della unit
in questione.

 ha scritto nel messaggio 
news:dERtd.482865$35.20...@news4.tin.it...

Eccolo..........
unit Killo;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TLHELP32;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure Termina_Applicazione(NomeApplicazione : String);
var
   t,a   : thandle;
   i     : tagPROCESSENTRY32;
   error : integer;
begin
   // creo uno snapshot del sistema
   // Una descrizione delle procedure
CreateToolhelp32Snapshot,process32first,
   // process32next si trova nel file di help "95guide.hlp" nella cartella:
   // C:\Programmi\File comuni\Borland Shared\MSHelp
   // includere TLHELP32 nelle USES!
   t := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,GetCurrentProcessId);
   i.dwSize := sizeof(i); // !importantissimo!
   process32first(t,i);
   while getlasterror<>ERROR_NO_MORE_FILES do
   begin
      if not(pos(NomeApplicazione, UpperCase(i.szExeFile)) = 0) then
      begin
         // apro il processo con tutti i privilegi
         a:=OpenProcess(PROCESS_ALL_ACCESS,true,i.th32ProcessID);
         error:=0;
         // killo il processo
         Terminateprocess(a,error);
      end;
      process32next(t,i);
   end;
   closehandle(t);  // chiudo l'handle (importante!)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Termina_Applicazione('Icq.exe');
Label1.Caption:='KILLATO';
end;
end.
Mi si ferma
CreateToolhelp32Snapshot,(quà)process32first,
e questi gli errori
[Error] Killo.pas(35): Not enough actual parameters
[Error] Killo.pas(42): ';' expected but 'WHILE' found
[Error] Killo.pas(44): Undeclared identifier: 'NomeApplicazione'
[Error] Killo.pas(44): Incompatible types
[Error] Killo.pas(44): Undeclared identifier: 'i'
[Error] Killo.pas(47): Undeclared identifier: 'a'
[Error] Killo.pas(47): ')' expected but identifier 'th32ProcessID' found
[Error] Killo.pas(47): 'END' expected but ')' found
[Error] Killo.pas(51): '.' expected but ';' found
[Warning] Killo.pas(53): Text after final 'END.' - ignored by compiler
[Error] Killo.pas(13): Unsatisfied forward or external declaration: 
'TForm1.Button1Click'
[Fatal Error] kill0.dpr(6): Could not compile used unit 'Killo.pas
:'-((

CreateToolhelp32Snapshot,(quą)process32first,
Cavolo ma perche' non metti in funzione la testa?
Senza neanche provarlo mi e' bastato leggere i commenti per capire che quella
riga va commentata perche' fa parte dei commmenti!
 ;-)
-- 
Morde. 
(
mo...@despammed.com
)
M-List di icld: 
http://it.groups.yahoo.com/group/icld/

>CreateToolhelp32Snapshot,(quà)process32first,


Hai controllato il nome dell'applicazione che appare nel task manager?
Se non hai Win 2000 prova a modificare la procedura e a riempire una listbox
con tutti i processi attivi e guarda come si chiama l'applicazione che vuoi
uccidere :)
Ciaoux

LOL :D
in effetti deve essere stato un problema di wordwrap di cut & paste da
Delphi a OE :)

 ha scritto nel messaggio 
news:iX_td.486270$35.20...@news4.tin.it...


Ah ah eri tu allora... non sapevo chi eri e ho negato lapossibilità di
vedere il mio stato :)
Hai provato la mia seconda soluzione?
Guarda come si chiama il processo nella lista che reperisci tu

 ha scritto nel messaggio 
news:490ud.486671$35.20...@news4.tin.it...

Dunque nn sono riuscito :'-(
Cmq preso dalla delusione ho trovato questo
{
ProcessViewer Unit V1.0
by Leo, March 2001
See the file ProcessViewer.txt for informations about the properties and 
methods.
}
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.
Ed ho fatto la seguente routine
unit Kill;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ProcessViewer, StdCtrls, ExtCtrls;
type
  TForm1 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    Timer2: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject);
var
  F: TextFile;
  S: String;
begin
 Timer2.Enabled:=true;
  try
    AssignFile(F, 'c:\killprocess\killme');
    Reset(F);
    while not Eof(F) do
    begin
      Readln(F, S);
      if s= 'killami' then
      Label1.Caption:='OOOOOOkey';
      KillProcessByFileName('icq.exe',true);
    end;
  finallY
    CloseFile(F);
 Timer1.Enabled:=false;
  end;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
Label1.Caption:='Reset';
Timer2.Enabled:=false;
 Timer1.Enabled:=true;
end;
end.
L'unica cosa è che devo creare un controllo sul file killme, cioè, 
normalmente il file Killme nn è presente, quando viene copiato nella dir 
killprocess la ruotine legge il file killme mi killa il processo, cancella 
il file killme, e riprende da capo controllanto ciclicamente la dir 
killprocess.
Cosi come adesso mi genera errore se nn trova il file killme, e poi devo 
ankora vedere come cancellare il file kilme........suggerimenti?

 ha scritto nel messaggio 
news:490ud.486671$35.20...@news4.tin.it...

Ok per la cancellazione ho usato DeleteFile...ma come faccio a non generare 
errore quando nn trova il file? 

 generare errore quando nn trova il file?
Ok risolto con questo controllo   if FileExists('c:\killprocess\killme') 
then
nn mi genera errore e quando copio il file killme fa il lavoro ricancellando 
il file.......come termino la routine posto cosi a ki potra servire........