Solved

exe file deletes itself

Posted on 2003-11-24
21
573 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

730 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