Icono
"Aplicación que se borra a sí misma"

 



Quizás te has visto en alguna ocasión ante la necesidad de eliminar tu aplicación una vez que ha terminado de realizar su trabajo. Pero ya sabes que el Sistema Operativo Windows se protege a si mismo de muchas formas distintas, y una de ellas es no permitir borrar un archivo ejecutable mientras está siendo ejecutado.

Entonces ¿como es posible que una aplicación pueda ejecutar alguna instrucción dentro de su propio código para que la aplicación se borre a sí misma?

El secreto está en la función SelfDelete que te muestro en el código del ejemplo siguiente.

Después de probar múltiples formas de intentar conseguir este proposito (que las muestro todas dentro del código de la "unit1.pas" en forma de comentarios) he comprobado que la más efectiva y de código más conciso es la que te muestro.

Es muy importante entender que esta función solo puede ser llamada en el evento FormClose del Formulario principal de la aplicación, es decir, que debe ser llamada justo antes de que la aplicación se cierre. Esto es debido a que lo que hace la función es llamar al sistema operativo para que este cree una nueva ventana de comandos (no visible) y ejecute la instrucción "del" sobre nuestro archivo ejecutable. Esto podrá tener éxito si en el tiempo que transcurre entre la llamada a la función y su ejecución por parte del S.O. nuestra aplicación ya se ha cerrado y desaparecido de la lista de tareas activas que controla el sistema.

A continuación, puedes ver el código completo de la app, y si lo deseas puedes descargarlo todo (código y app) en un archivo "zip".

Unit1.pas
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


uses shellapi;

procedure SelfDelete;
var
  szFile, szCmd: array [ 0 .. MAX_PATH - 1 ] of char;
begin
  if((GetModuleFileName(0,szFile,MAX_PATH)<>0) and
     (GetShortPathName(szFile,szFile,MAX_PATH)<>0)) then
  begin
    lstrcpy(szCmd,'/c del ');
    lstrcat(szCmd,szFile);
    lstrcat(szCmd,' >> NUL');
    if Windows.GetEnvironmentVariable('ComSpec',szFile,MAX_PATH)<>0 then
       ShellExecute(0,nil,szFile,szCmd,nil,SW_HIDE);
  end;
end;


{

procedure SelfDelete1;
var
   cmd, s : string;
   n:dword;
begin                          // !!!! milisegundos de espera antes de borrar
     s:= '/C ping 1.1.1.1 -n 1 -w 3000 >> nul & del "'+paramstr(0)+'" >> nul';
     setlength(cmd,256);
     n:=GetEnvironmentVariable('ComSpec', pchar(cmd), 255);
     if n<>0 then begin
       setlength(cmd,n);
       //WinExec(pchar(cmd + ' '+ s),sw_hide);
       ShellExecute(0, 'open', pchar(cmd), pchar(s), nil, sw_hide);
     end;
end;




procedure SelfDelete2;
var s: string;
    f: textfile;
begin
    s:= GetTmpFileName('.bat');;

    AssignFile(f,s);
    Rewrite(f);
    Writeln(f,':f');
    Writeln(f, 'del "'+ Paramstr(0)+'"');
    WriteLn(f,'if EXIST "'+ pARAMSTR(0) + '" GOTO f');
    WriteLn(f,'del "'+ s +'"');
    CloseFile(f);
    WinExec(pchar(s), sw_hide);
end;

procedure SelfDelete3;
var
    F: TextFile;
    batName: string;
    pi: TProcessInformation;
    si: TStartupInfo;
begin
    batName := ExtractFilePath(ParamStr(0)) + '$$$$$$$$.bat';
    AssignFile(F,batName);
    Rewrite(F);
    Writeln(F,':try');
    Writeln(F,'del "'+ParamStr(0)+'"');
    Writeln(F,'if exist "'+ ParamStr(0)+'"'+' goto try');
    Writeln(F,'del "' + batName + '"' );
    CloseFile(F);

    FillChar(si, SizeOf(si), $00);
    si.dwFlags := STARTF_USESHOWWINDOW;
    si.wShowWindow := SW_HIDE;
    //MessageBox(0,'Antes de lanzar el bat','Dentro de SelfDelete',MB_OK);
    //Quitamos los atributos de oculto y solo lectura para que no falle el .bat
    SetFileAttributes( PChar( ParamStr(0) ), 0 );
    if CreateProcess( nil, PChar(batName), nil, nil, False,
                      IDLE_PRIORITY_CLASS, nil, nil, si, pi ) then
       begin
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            //MessageBox(0,'Lanzado el proceso bat','Dentro de SelfDelete',MB_OK);
       end;
    //MessageBox(0,'Lanzado el proceso bat','Dentro de SelfDelete',MB_OK);
    Halt;
end;



procedure SelfDelete4;
var
  szFile, szCmd: array [ 0 .. MAX_PATH - 1 ] of char;
begin
  //if((GetModuleFileName(0,szFile,MAX_PATH)<>0) and
  //   (GetShortPathName(szFile,szFile,MAX_PATH)<>0)) then
  begin
    lstrcpy(szCmd,'/c del ');
    //lstrcat(szCmd,szFile);
    lstrcat(szCmd, pchar('"'+Paramstr(0)+'"'));
    lstrcat(szCmd,' >> NUL');


    if Windows.GetEnvironmentVariable('ComSpec',szFile,MAX_PATH)<>0 then
       ShellExecute(0,nil,szFile,szCmd,nil,SW_HIDE);
  end;
end;



procedure SelfDelete5;
var
  szFile, szCmd: array [ 0 .. MAX_PATH - 1 ] of char;
begin
  if((GetModuleFileName(0,szFile,MAX_PATH)<>0) and
     (GetShortPathName(szFile,szFile,MAX_PATH)<>0)) then
  begin
    //showmessage(szfile);
    lstrcpy(szCmd,'/c del ');
    lstrcat(szCmd,szFile);
    lstrcat(szCmd,' >> NUL');
 
    if Windows.GetEnvironmentVariable('ComSpec',szFile,MAX_PATH)<>0 then  begin
      //showmessage(szfile+szCmd);
      ShellExecute(0,nil,szFile,szCmd,nil,SW_HIDE);
      //WinExec(pchar(szFile + ' '+ szCmd),sw_hide);

    end;
  end;
end;


}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SelfDelete;
end;

end.
Puede descargar el código fuente anterior con este enlace:
codigo-fuente-selfdelete.zip
Puede encontrar una versión Portable de Delphi en esta dirección:
http://www.andyaska.com/?act=download&id=34&mode=detail

O puede descargar la versión gratuita Delphi Starter directamente desde su web oficial: https://www.embarcadero.com/products/delphi/starter/free-download
 
Delphi Source Code
Auto eliminar .exe



Descargar Auto eliminar .exe Windows 10 Compatible


logo-MecaNet
Certificado de seguridad del sitio













© Carlos Miguel Cáceres García