Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Inno Setup to uninstall everything?

Tags:

inno-setup

I am new to Inno Setup. Stuck on one issue ~ how to configure the uninstall piece to remove all files, folders, subfolders, and even new files/folders etc. created by application (in other words, a 100% removal of the application and associated files).

I hunted around here and also on their forum, and came up empty. Can anyone point me to a document, FAQ etc. regarding how to do this?

UPDATE

Thanks for all the feedback so far (very awesome). So it looks like I can delete everything using the {app}*.* directive in the uninstall section. Also looks like everyone is advising against it. So the question now becomes (I am wondering if this should be a totally new question) is there a way during the uninstall that we can ask the user 'Do you want to remove all project files associated with this application?' and if they answer YES, to run the uninstall {app}*.* piece?

Thanks -

like image 341
OneNerd Avatar asked Mar 13 '09 16:03

OneNerd


People also ask

How do I Setup an inno compiler?

Go to Menu, Project, then Compile to compile and create the setup file. This will create a complete installer. Run the Setup and your application will be installed correctly. Innosetup offers an awesome alternative to create great looking Installers for free.

How do you write an Inno Script?

The Inno Setup Example Scripts are located in a separate folder. Please click the "Inno Setup Example Scripts" shortcut created in the Start Menu when you installed Inno Setup, or open the "Examples" folder in your Inno Setup directory.


3 Answers

I think the recommended approach is to specify what to remove in the uninstall section. The reasoning is that what if for whatever reason the user decided to put their own files in your installation directory that they didn't want removed, or saved data that they might want to keep around (maybe they uninstall is to install a newer version?)

That being said, I don't know offhand what the script is, but if you use ISTool (highly recommend) just got to the Uninstall Delete section and add things you want removed. It should present all the possible options in a nice GUI and generate the script for you.

Edit: An example from the Inno Setup documentation:

[UninstallDelete]
Type: files; Name: "{win}\MYPROG.INI"

But they strongly you don't do something like

[UninstallDelete]
Type: files; Name: "{app}\*.*"

NOTE: Don't be tempted to use a wildcard here to delete all files in the {app} directory. I strongly recommend against doing this for two reasons. First, users usually don't appreciate having their data files they put in the application directory deleted without warning (they might only be uninstalling it because they want to move it to a different drive, for example). It's better to leave it up to the end users to manually remove them if they want. Also, if the user happened to install the program in the wrong directory by mistake (for example, C:\WINDOWS) and then went to uninstall it there could be disastrous consequences. So again, DON'T DO THIS!

like image 145
Davy8 Avatar answered Oct 09 '22 19:10

Davy8


You should probably have made this a totally new question, but I'll answer your updated question here as well. Have a look at the section "Pascal Scripting: Uninstall Code" in the Inno Setup Documentation.

To give an example how to conditionally delete data files as part of the uninstallation process:

[Code]

procedure DeleteBitmaps(ADirName: string);
var
  FindRec: TFindRec;
begin
  if FindFirst(ADirName + '\*.*', FindRec) then begin
    try
      repeat
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then begin
          if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
            DeleteBitmaps(ADirName + '\' + FindRec.Name);
            RemoveDir(ADirName + '\' + FindRec.Name);
          end;
        end else if Pos('.bmp', AnsiLowerCase(FindRec.Name)) > 0 then
          DeleteFile(ADirName + '\' + FindRec.Name);
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usUninstall then begin
    if MsgBox('Do you want to delete all data files?', mbConfirmation,
        MB_YESNO) = IDYES 
    then begin
      DeleteBitmaps(ExpandConstant('{app}'));
    end;
  end;
end;

But depending on the amount of stuff you need to clean up you might be better off to create a special helper program that is part of the installation, and which can be executed during the uninstallation of the app (using an entry in the [UninstallRun] section).

like image 36
mghie Avatar answered Oct 09 '22 19:10

mghie


There are cases to want to delete files which were not initially written to the user's disk at time of installation. One of these cases is when you have an application that updates itself when it is started. New files can be added to the disk in this manner which are not a part of the uninstaller.

For this case I suggest that you create a "patch manifest" file which keeps a running record of what files should be in the {app} directory. Find below a sample of code that reads from a file in the {app} dir called 'patch_manifest.txt'

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  i: Integer;
  arrayLen: Longint;
  item: String;
  itemsToDelete: Array of String;
begin
  case CurUninstallStep of
    usUninstall:
      begin
        LoadStringsFromFile(ExpandConstant('{app}') + '\patch_manifest.txt', itemsToDelete);
        arrayLen := GetArrayLength(itemsToDelete);
        for i := 0 to arrayLen-1 do
          begin
          item := ExpandConstant('{app}') + '\' + itemsToDelete[i];
          if FileExists(item) then
            DeleteFile(item);
          if DirExists(item) then
            RemoveDir(item);
          end;
      end;
  end;
end;

and a sample of the patch_manifest.txt

data/something_here.dat
data/moredatahere.dat
data/
Launcher.exe
patch_manifest.txt

Note: The order of the lines in the patch_manifest is important. All files within a directory should first be listed followed by the directory - directories which are not empty cannot be delete.

Your application should be shipped with a patch_manifest and the patch_manifest should be updated with every patch. Make this part of your build process so you don't forget to update it!

It is very important that you do not delete by wildcard (.) even if you prompt the user. Uninstaller's have elevated privileges which could potentially destroy a user's computer. Take the case of a user who accidentally installed your application to C:\Windows\ or C:\Program Files.

Another good idea is to verify that the file is in fact "your file" by performing an MD5 check prior to deleting it. In this case your patch_manifest.txt would not only include the relative path to the file but also the MD5 checksum.

like image 42
reset Avatar answered Oct 09 '22 18:10

reset