Solved

exe file deletes itself

Posted on 2003-11-24
21
564 Views
Last Modified: 2010-05-18
How can I make the executing exe file to delete itself after an uninstallation?
0
Comment
Question by:qweqwe
  • 6
  • 4
  • 4
  • +3
21 Comments
 
LVL 2

Expert Comment

by:-Karamja-
ID: 9811611
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
 
LVL 8

Expert Comment

by:gmayo
ID: 9811807
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
 
LVL 3

Accepted Solution

by:
fibdev earned 125 total points
ID: 9812001
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
 
LVL 8

Expert Comment

by:gmayo
ID: 9812866
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
 
LVL 2

Expert Comment

by:-Karamja-
ID: 9813068
You wont need the -y on the end of the bat commands sorry my bad ;P
0
 
LVL 3

Expert Comment

by:fibdev
ID: 9813766
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
 
LVL 2

Expert Comment

by:TheLeader
ID: 9815362
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
 
LVL 3

Expert Comment

by:fibdev
ID: 9815437
I see why you are called TheLeader...

Your Kung Fu is strong.  We are not worthy.

:)
0
 
LVL 2

Expert Comment

by:TheLeader
ID: 9815716
thanx ;)
0
 
LVL 1

Expert Comment

by:winexec
ID: 9816141
@gmayo: if the program terminates why is necessary to free the used objects?
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 8

Expert Comment

by:gmayo
ID: 9816545
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
 
LVL 2

Expert Comment

by:TheLeader
ID: 9817305
"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
 
LVL 8

Expert Comment

by:gmayo
ID: 9818206
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
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9841083
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
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9841104
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
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9841114
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
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9841118
not kung foo but the force :o)
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9841130
   // 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
 
LVL 3

Expert Comment

by:fibdev
ID: 9846752
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
 
LVL 3

Expert Comment

by:SteveWaite
ID: 9846782
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
 
LVL 2

Expert Comment

by:TheLeader
ID: 9846858
Thank you "fibdev", and Congratulation ...
anyway, more skills what Im looking for.

I can't deny the points, but in another Question ;)
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

747 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

10 Experts available now in Live!

Get 1:1 Help Now