24

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 -

OneNerd
  • 6,442
  • 17
  • 60
  • 78
  • 5
    I think the reason this doesn't usually come up is that a well-behaved app doesn't store user-created content in its {app} folder. Under the least user access model, the actual user would typically not be able to write there in any case. That is why the Application Data folder exists. – RBerteig Mar 18 '09 at 07:29
  • 3
    I have the issue where my product updates itself which may add new files. These are product files, not data files. They really need to be uninstalled along with the product, but at install time these files were unknown. So there is a legitimate reason to delete files at uninstall time that weren't put there at install time. – Charles Aug 28 '09 at 17:58
  • 2
    If you have an update case, then the update should be performed by an updated Inno installer. Thus it will automatically add the new files to be uninstalled, and you don't have to do anything special. (Remember, the application is running as non-admin, and the install/upgrade requires admin permissions, so the app can't upgrade itself without running a separate elevated installer anyway.) – Miral Jan 02 '13 at 12:08
  • What if the application is, say, a custom Java Runtime, and every user gets, after installation, a per-user JAR that contains the main application logic? It makes sense that the data would be protected as READ only, in the application folder, and not in the appdata folder – claude Nov 24 '22 at 00:52

9 Answers9

17

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!

Davy8
  • 30,868
  • 25
  • 115
  • 173
  • 1
    Thanks Davy ~ so you are saying there is no way to specify that files added AFTER the installation get deleted? – OneNerd Mar 13 '09 at 16:54
  • You can, you just need to tell it what those files or folders are. – Davy8 Mar 13 '09 at 18:11
  • .. and if I do not know what those file/folders are ahead of time (which I do not), then I assume as Ken White has proclaimed, that there is no way to do that? – OneNerd Mar 13 '09 at 19:44
  • Well (I think) you can set tell it to delete the install directory and all files inside it. I'm just saying that it doesn't do it by default and has a good reason not to. Will edit answer with more info. – Davy8 Mar 13 '09 at 21:03
  • 2
    There's a good reason this capability is not recommended. On the other hand, a well-behaved app shouldn't be writing to its install folder either, since that makes it harder to use on Vista or XP by a non-admin user. – RBerteig Mar 13 '09 at 21:29
13

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

mghie
  • 32,028
  • 6
  • 87
  • 129
  • Seems like nobody clicked "NO" at "Do you want to delete all data files?". This does not work! Just tested the procedure CurUninstallStepChanged in UninstallCodeExample1.iss – Jens A. Koch Jan 20 '13 at 23:28
  • 5
    **This is very dangerous.** **It will recursively delete the content of a symlinked folder or reparse point.** I advise a) to not use this function without a modification to the Attributes check and b) Innosetup has a method `DelTree()`, which is simply better and more secure. It also lifts any read-only attributes, before deletion and "does not step into" symlinks, but removes them. – Jens A. Koch Jul 04 '15 at 08:57
6

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.

reset
  • 96
  • 1
  • 2
  • Note that under Vista+ UAC rules (or pre-Vista limited-user rules), the app can't update itself directly in this manner anyway -- it can only do so by running an elevated installer. And if that elevated installer is an Inno Setup installer, then there is no problem -- it will add the new files to the existing uninstall log and they will be removed on uninstall as expected. – Miral Sep 30 '12 at 23:34
4

This should do the trick:

[Dirs]
Name: "{app}"; Flags: uninsalwaysuninstall
Scoox
  • 87
  • 2
  • 5
  • From inno setup help it will uninstall only if it's empty, so it won't work: uninsalwaysuninstall Instructs the uninstaller to always attempt to delete the directory if it's empty. Normally the uninstaller will only try to delete the directory if it didn't already exist prior to installation. – htzfun Dec 05 '17 at 01:42
4

Add delete file/folder item in Inno Setup studio. Or directly use the script as follows.

[Generated code sample]

[UninstallDelete]
Type: filesandordirs; Name: "{app}\unnecessary_files"
Naveen Kumar V
  • 2,559
  • 2
  • 29
  • 43
4

You can't use InnoSetup to uninstall anything it didn't install, and you shouldn't want to do so. I for one would be very unhappy if I installed an application, entered a lot of data, and then decided to use something else instead that would read that data from your app. If your uninstall killed all of the work I'd already done, I might be tempted to come looking for you. And probably not to buy you a cup of coffee.

Or consider the case where I install your application in the process of evaluating several. I try the apps, and keep going back to yours because I like it a little better, and each time I enter more data. Then I decide not to do anything for a while, so I remove all the test apps. In a week, I decide I need to use your app now after all, and I reinstall it. Oops! All of the work I did testing it that I now wanted to use is gone.

The above is why, when you uninstall an application, it leaves behind anything you created in the folders, like configuration files, data files, etc. It doesn't know what you want it to do with them, so it leaves them alone.

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Technically you can, but you shouldn't. See the [UninstallDelete] section if you think you are fireproof and impervious to pitchfork-wielding angry mobs of users. But really, don't do it. It is there so that an application that leaks things like help index files when running can delete them. – RBerteig Mar 13 '09 at 21:32
  • Thanks for the correction. I've never researched it in that depth, as I'm not fireproof and impervious. I'm also not up for being sued if my uninstall deletes something really important to one of my customers. – Ken White Mar 13 '09 at 23:18
  • Agree, but what about files and folders your application [creates after the install](http://www.vbforums.com/showthread.php?848531-Installers-and-Uninstalling)? – Laurie Stearn Jun 10 '17 at 09:17
  • @Laurie: Inno won't remove those, for common sense reasons. A) the uninstaller doesn't know they exist, and B) they're the users files, and accidentally deleting a file critical to the user could be very bad. – Ken White Jun 11 '17 at 00:37
  • @Ken: Yes thorny issue, currently writing a script that asks the user about those in the uninstall process. Will post it at the thread linked above, but only after a fair bit of testing! – Laurie Stearn Jun 11 '17 at 09:24
  • @LaurieStearn: Not only *thorny*, but potentially expensive. If the user accidently saves their important data in your application's folder (which is highly possible - I have users all the time that use Save As to save an email attachment and have no idea where they saved it afterward) and your uninstall deletes it, in some jurisdictions and circumstances you could be held legally and financially liable for damages. – Ken White Jun 13 '17 at 01:57
  • @Ken: The script will not automatically delete anything, It prompts for confirmation on any item or directory. In any case wouldn't misuse of the script be covered by a disclaimer (mine, not Inno's), and shouldn't Inno change the working directory back to whatever it was before Inno launched, when the install completes? Of course there is no problem if Inno actually plans to implement a _movetorecycle_ function. :) – Laurie Stearn Jun 13 '17 at 12:09
2

I wanted to delete gData.dat which created on run time in installed folder

and was working fine for me

[UninstallDelete]
Type: files; Name: "{app}\gData.dat"
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
1

Isn't that the default if your don't specify "uninsneveruninstall" for an entry?

edit - Sorry I hadn't realised you were talking about newly created data files.

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Don't believe so, it should only uninstall files that it created and has no knowledge of what your application would have created. (Someone correct me if I'm wrong) – Davy8 Mar 13 '09 at 16:40
  • Not sure (again, I am new to Inno Setup), but when I uninstall our application, it leaves any new files created (and consequently, folders the exist in). I believe because of this, the install folder is also not removed. Thanks ~ – OneNerd Mar 13 '09 at 16:44
  • If I'm not mistaken it only removes files it creates, and only removes the folder if it's empty. This is default for a very good reason (see my answer) – Davy8 Mar 13 '09 at 16:46
-1

To delete everything I use this :

[UninstallDelete]
Type:files; Name: "{app}"
Opal
  • 81,889
  • 28
  • 189
  • 210
Matzora
  • 31
  • 3