Solved

exe file deletes itself

Posted on 2003-11-24
21
574 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

Independent Software Vendors: 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!

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…

729 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