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 -
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.
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.
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!
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With