Newsgroup: it.comp.lang.delphi
Titolo: Eseguibile che cancella se stesso al termine.

Come potrei implementare un eseguibile che, al termine dell'esecuzione, 
cancelli se stesso, senza usare il sistema suggerito da Andrea Gnesutta del 
file BAT ?
http://66.249.93.104/search?q=cache:3kLMnYhfRKAJ:www.delphiedintorni.it/geo
xml/contentgetnews/%257B8CF7B423-323E-4DF6-B99F-
27D756F7E03A%257D.htm+eseguibile+cancella+stesso&hl=it
Questo ovviamente non funziona:
program Project1;
uses
  SysUtils;
begin
  Application.Initialize;
  Application.Run;
  DeleteFile(Application.ExeName)
end.
---------------------------
e questo neppure (derivato dal tip di Andrea Gnesutta - codice che richiamo 
nell'evento OnDestroy della form principale dell'applicazione):
uses ShellAPI;
procedure ExecuteAndWait(const FileName: string; Wait: Boolean);
var
  SEI: TShellExecuteInfo;
begin
// Inizializzo la struttura con i parametri.
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  if Wait then
// Questo flag è necessario perché il campo
// hProcess venga restituito in output.
    SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpFile := PChar(FileName);
// Per mostrare l'applicazione lanciata.
  SEI.nShow := SW_NORMAL;
  if ShellExecuteEx(@SEI) then
  begin
    if Wait then
// Aspetto che il processo termini.
      WaitForSingleObject(SEI.hProcess, INFINITE);
// Rilascio il process handle.
    CloseHandle(SEI.hProcess);
  end;
end;
procedure KillMe;
var
  s, sEXE: string;
begin
  s := ExtractFilePath(Application.ExeName)+ 'delapp.bat';
  sEXE := Application.ExeName;
  with TStringList.Create do
  try
    Add(':inizio');
    Add(Format('DEL "%s"', [sEXE]));
    Add(Format('IF EXIST "%s" GOTO inizio', [sEXE]));
    Add(Format('DEL "%s"', [sEXE]));
    try
      SaveToFile(s);
      ExecuteAndWait(s, True);
    finally
      DeleteFile(s)
    end
  finally
    Free
  end
end;
-------------------------------------------
adesso sto pensando a un ESEGUIBILE_B inglobato come risorsa 
nell'ESEGUIBILE_A, che:
- al termine dell'esecuzione di ESEGUIBILE_A,
- viene estratto l'ESEGUIBILE_B,
- che cancella ESEGUIBILE_A
ma mi resta pur sempre ESEGUIBILE_B, poi!
-- 
Mauro Falzari 
 
 "Se guardi nell'abisso, anche l'abisso guarda in te." 
   (Friedrich Nietzsche)

ho risolto da me nel giro di poco, in effetti bastava aggiungere alla fine 
del file BAT una riga che cancella se stesso, ecoc il codice funzionante 
(o almeno così pare):
program Project1;
{***********************************************************************
    Eseguibile che cancella se stesso
    ---------------------------------
    Mauro Falzari - novembre 2005 - 
mauro_...@despammed.com
    -----------------------------------------------------------
    riferimenti:
    § post di Nando Dessena su 
www.delphiedintorni.it
 21-giu-00
 
http://tinyurl.com/dnx5s
    § post di Andrea Gnesutta su 
www.delphiedintorni.it
 11-lug-01
 
http://tinyurl.com/a8vxk
***********************************************************************}
uses
  Windows, Classes, SysUtils, ShellAPI;
procedure ExecuteAndWait(const FileName: string; Wait: Boolean);
var
  SEI: TShellExecuteInfo;
begin
// Inizializzo la struttura con i parametri.
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  if Wait then
// Questo flag è necessario perché il campo
// hProcess venga restituito in output.
    SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpFile := PChar(FileName);
// Per mostrare l'applicazione lanciata.
  SEI.nShow := SW_NORMAL;
  if ShellExecuteEx(@SEI) then
  begin
    if Wait then
// Aspetto che il processo termini.
      WaitForSingleObject(SEI.hProcess, INFINITE);
// Rilascio il process handle.
    CloseHandle(SEI.hProcess);
  end;
end;
var
  sBat, sExe: string;
const
  BAT_NAME = 'delete_me.bat';
begin
  sExe := ParamStr(0);
  sBat := IncludeTrailingPathDelimiter(ExtractFilePath(sExe)) + BAT_NAME;
  with TStringList.Create do
  try
    Add(':inizio');
    Add(Format('DEL "%s"', [sExe]));
    Add(Format('IF EXIST "%s" GOTO inizio', [sExe]));
    Add(Format('DEL "%s"', [sExe]));
    Add(Format('DEL "%s"', [sBat]));
    DeleteFile(sBat);
    SaveToFile(sBat);
  finally
    Free
  end;
  ExecuteAndWait(sBat, False);
end.


se può essere utile, questo è il codice come sopra, ma con una form:
program Project1;
{***********************************************************************
    Eseguibile che cancella se stesso - con form
    --------------------------------------------
    Mauro Falzari - novembre 2005 - 
mauro_...@despammed.com
    -----------------------------------------------------------
    riferimenti:
    § post di Nando Dessena su 
www.delphiedintorni.it
 21-giu-00
 
http://tinyurl.com/dnx5s
    § post di Andrea Gnesutta su 
www.delphiedintorni.it
 11-lug-01
 
http://tinyurl.com/a8vxk
***********************************************************************}
uses
  Windows,
  Classes,
  SysUtils,
  ShellAPI,
  Forms,
  Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
procedure ExecuteAndWait(const FileName: string; Wait: Boolean);
var
  SEI: TShellExecuteInfo;
begin
// Inizializzo la struttura con i parametri.
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  if Wait then
// Questo flag è necessario perché il campo
// hProcess venga restituito in output.
    SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpFile := PChar(FileName);
// Per mostrare l'applicazione lanciata.
  SEI.nShow := SW_NORMAL;
  if ShellExecuteEx(@SEI) then
  begin
    if Wait then
// Aspetto che il processo termini.
      WaitForSingleObject(SEI.hProcess, INFINITE);
// Rilascio il process handle.
    CloseHandle(SEI.hProcess);
  end;
end;
var
  sBat, sExe: string;
const
  BAT_NAME = 'delete_me.bat';
begin
  sExe := ParamStr(0);
  sBat := IncludeTrailingPathDelimiter(ExtractFilePath(sExe)) + BAT_NAME;
  with TStringList.Create do
  try
    Add(':inizio');
    Add(Format('DEL "%s"', [sExe]));
    Add(Format('IF EXIST "%s" GOTO inizio', [sExe]));
    Add(Format('DEL "%s"', [sExe]));
    Add(Format('DEL "%s"', [sBat]));
    DeleteFile(sBat);
    SaveToFile(sBat);
  finally
    Free
  end;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
  ExecuteAndWait(sBat, False);
end.


 file BAT ?
Forse creando una chiave nel registro
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
Windows\CurrentVersion\RunOnce
con un comando del genere:
cmd.exe /C del "Path dell'applicazione"
Però non viene cancellato subito ma solo al riavvio di Windows.
Vedi anche queste discussioni:
http://216.101.185.148/scripts/isapi.dll/thread?id=368F6784&thread=1448351
http://216.101.185.148/scripts/isapi.dll/article?id=368F6784&article=5922408
Oppure questa, dove c'è anche del codice ASM che sarebbe carino provare
se funziona (non ho Delphi sottomano):
http://www.delphi3000.com/articles/article_514.asp?SK=
HTH
Ciao
-- 
ACSH
[D4]
Chi fa da se', fatica il doppio