exe file deletes itself

How can I make the executing exe file to delete itself after an uninstallation?
qweqweAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

-Karamja-Commented:
Hmm,

You could make your app make and run a bat file.

eg

@ECHO OFF
del C:\Thisapp.exe -y
del C:\Thisbat.bat -y

This will delete your exe and then the bat file will delete its self
0
gmayoCommented:
The registry has a RunOnce section you can use. It processes this on start-up (possibly after logging back in without restarting, but I'm not sure on this).

Geoff M.
0
fibdevCommented:
To elaborate on -Karamja-'s example...

The problem is executing the bat file <i>after</i> the application closes.  As long as your app is running, the source file can't be deleted.  Maybe someone else will have time to sort this out for you.

// Happy Coding :)

---------------------------------------------------------------------------------

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var MakeBat: TStringList;
begin
    MakeBat := TStringList.Create;
    MakeBat.Add('@ECHO OFF');
    makebat.Add('del ' + application.exename + ' -y');
    makebat.Add('del' + ' die.bat -y');
    makebat.SaveToFile('.\die.bat');
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
   ShellExecute(ValidParentForm (Self).Handle,'Open', PChar('.\die.bat'), nil, nil, SW_HIDE);
end;

end.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

gmayoCommented:
Ooh, a memory leak! makebat.Free please. Perhaps you can add a delay to the batch file so your program has a chance to terminate.

Geoff M.
0
-Karamja-Commented:
You wont need the -y on the end of the bat commands sorry my bad ;P
0
fibdevCommented:
procedure SmackForhead(AssociatedNoise : TNoise; AssociatedQuestion: TQuestion);
begin
  ShowMessage('Oooops, I forgot to free up that stringlist!');
end;

procedure TQuestionOnLoad(Sender:TObject);
begin
  SmackForhead('Doh!', 'MyBad?');
end;  // Happy Coding :)
0
TheLeaderCommented:
procedure DeleteExe;
const
  cBatCode = ':delete_exe' + #13 +
             'del %s' + #13 +
             'if exist %s goto delete_exe' + #13 +
             'del %s';

var
  List : TStringList;
  BatPath : string;
  S    : string;
  PI : TProcessInformation;
  SI : TStartupInfo;
begin
  BatPath := ChangeFileExt(ParamStr(0), '.BAT');
  List    := TStringList.Create;
  try
    S := Format(cBatCode, [ParamStr(0), ParamStr(0), BatPath]);
    List.Text := S;
    List.SaveToFile(BatPath);
  finally
    List.Free;
  end;

  FillChar(SI, SizeOf(SI), 0);
  SI.dwFlags      := STARTF_USESHOWWINDOW;
  SI.wShowWindow  := SW_HIDE;
  if CreateProcess( nil, PChar(BatPath), nil, nil, False, IDLE_PRIORITY_CLASS, nil, nil, SI, PI) then
  begin
    CloseHandle(PI.hThread);
    CloseHandle(PI.hProcess);
  end;

end;

The above deletes its own executable. It's easy to convert it to delete any other exe.
0
fibdevCommented:
I see why you are called TheLeader...

Your Kung Fu is strong.  We are not worthy.

:)
0
TheLeaderCommented:
thanx ;)
0
winexecCommented:
@gmayo: if the program terminates why is necessary to free the used objects?
0
gmayoCommented:
It's called good programming practice. Technically, no you don't need to, but it is untidy and sloppy leaving allocated memory laying around. I'm not getting at fibdev here, who probably just forgot and would never do it in his own programs ;-), just explaining why it is so.

TheLeader - that's a bit processor-intensive isn't it? Why not insert a delay like I suggested earlier?

Geoff M.
0
TheLeaderCommented:
"gmayo" well, if you end the exe file without waiting the result, it will work without a doubt, but avoiding memory leaks, its more better.

Program long -> more memory resources -> Slow PC -> hang.
after that, the programmer will be dead meat ;)
0
gmayoCommented:
In the second or so that it takes a program to end and unlock itself (ie the exe), your batch file will be looping around madly attempting to delete it. While it is madly looping around, it'll be hogging the processor. I'm not saying it won't work, but IMHO is just not the best way. All you need do is add a pause like I suggested earlier...

Geoff M.
0
SteveWaiteCommented:
in 95,98,me

procedure TForm1.DeleteUninstallFileWithBat;
var
  F: Textfile;
  S: String;
begin
  S := Application.ExeName;
  AssignFile(F, ChangeFileExt(Application.ExeName, '.bat'));
  ReWrite(F);
  Writeln(F, ':1');
  Writeln(F, Format('del "%s"', [Application.ExeName]));
  Writeln(F, Format('if exist "%s" goto 1', [Application.ExeName]));
  Writeln(F, Format('del "%s"', [ChangeFileExt(Application.ExeName, '.bat')]));
  CloseFile(F);
  ExecuteFile(ChangeFileExt(Application.ExeName, '.bat'), '', PathEndOff(Application.ExeName), SW_HIDE);
end;

in nt and xp you add to [rename] section of Wininit.ini:
NULL=C:\WINDOWS\MyUninstaller.exe

Regards
Steve

0
SteveWaiteCommented:
you may need to use wininit.ini or
MoveFileEx(PChar(ExePath), nil, MOVEFILE_DELAY_UNTIL_REBOOT);
in any event if the user is looking at the file or directory with explorer when uninstalling!
0
SteveWaiteCommented:
sorry make that:
attempt to remove everything (NT OR win95,98,me) with RmDir() etc. , THEN check to see if the directory and files are there or not and use the wininit.ini in win95 and MoveFileEx() in NT to defer the removal, and finally use the batch file method for the uninstaller

Regards
Steve
0
SteveWaiteCommented:
not kung foo but the force :o)
0
SteveWaiteCommented:
   // Adding to [rename] section of Wininit.ini: NULL=C:\WINDOWS\MyUninstaller.exe

var
  IniItem: TIniFile;
begin
  IniItem := TIniFile.Create(<WinDirectory> + '\wininit.ini');
  with IniItem do
  try
    WriteString('rename', 'NULL', <ExePath>))
  finally
    Free;
  end;
end;
0
fibdevCommented:
Thanks for the points and the grade, but didn't some other experts offer more accurate suggestions?  I hate to see stuff like that go unrewarded.  Talant aside, In my personal opinion, SteveWaite and TheLeader are more learned than myself.
0
SteveWaiteCommented:
Thank you fibdev, but let me assure you i'm not worried about points, i was just here putting something back in. Glad to have helped you all.
0
TheLeaderCommented:
Thank you "fibdev", and Congratulation ...
anyway, more skills what Im looking for.

I can't deny the points, but in another Question ;)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.