I have a common application -like a media player- for each different retail product that is installed in the same folder i.e.
C:\\program files\\myapp
Inno Setup does not support partial uninstallations.
Once the uninstallation completes, your whole application with all installed components (movies) will be deleted.
What you can do is to present a custom form with movies list in the InitializeUninstall
. If the user chooses to uninstall only (some) movies, but not whole application (the viewer), you delete the movies with your own code and abort the uninstallation (by returning False
from the InitializeUninstall
). If the user chooses to uninstall everything, you let the uninstallation complete.
function InitializeUninstall(): Boolean;
var
Form: TSetupForm;
OKButton, CancelButton: TNewButton;
CheckListBox: TNewCheckListBox;
I, Count, Deleted: Integer;
FindRec: TFindRec;
MoviePath: string;
Movies: TArrayOfString;
begin
MoviePath := ExpandConstant('{app}\movies\');
Count := 0;
if FindFirst(MoviePath + '*', FindRec) then
begin
try
repeat
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
begin
Inc(Count);
SetArrayLength(Movies, Count);
Movies[Count - 1] := FindRec.Name;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end;
if Count = 0 then
begin
Log('Found no movies proceeding with a complete uninstallation');
Result := True;
end
else
begin
Log(Format('Found %d movies', [Count]));
Form := CreateCustomForm();
try
Form.ClientWidth := ScaleX(350);
Form.ClientHeight := ScaleY(250);
Form.Caption := 'Uninstall';
Form.Position := poDesktopCenter;
CheckListBox := TNewCheckListBox.Create(Form);
CheckListBox.Parent := Form;
CheckListBox.Left := ScaleX(10);
CheckListBox.Width := Form.ClientWidth - 2*CheckListBox.Left;
CheckListBox.Top := ScaleY(10);
CheckListBox.Height :=
Form.ClientHeight - ScaleY(23 + 10 + 10 + CheckListBox.Top);
CheckListBox.AddCheckBox(
'Uninstall viewer and all movies', '', 0, True, True, True, True, nil);
for I := 0 to Count - 1 do
begin
CheckListBox.AddCheckBox(Movies[I], '', 1, True, True, False, True, nil);
end;
OKButton := TNewButton.Create(Form);
OKButton.Parent := Form;
OKButton.Width := ScaleX(75);
OKButton.Height := ScaleY(23);
OKButton.Left := Form.ClientWidth - ScaleX(75 + 6 + 75 + 10);
OKButton.Top := Form.ClientHeight - ScaleY(23 + 10);
OKButton.Caption := 'OK';
OKButton.ModalResult := mrOk;
OKButton.Default := True;
CancelButton := TNewButton.Create(Form);
CancelButton.Parent := Form;
CancelButton.Width := OKButton.Width;
CancelButton.Height := OKButton.Height;
CancelButton.Left := OKButton.Left + OKButton.Width + ScaleX(6);
CancelButton.Top := OKButton.Top;
CancelButton.Caption := 'Cancel';
CancelButton.ModalResult := mrCancel;
CancelButton.Cancel := True;
Form.ActiveControl := CheckListBox;
if Form.ShowModal() <> mrOk then
begin
Log('User cancelled the uninstallation');
Result := False;
end
else
begin
if CheckListBox.State[0] = cbChecked then
begin
Log('User selected complete uninstallation');
Result := True;
end
else
begin
for I := 0 to Count - 1 do
begin
if CheckListBox.Checked[I + 1] then
begin
if DeleteFile(MoviePath + Movies[I]) then
begin
Inc(Deleted);
Log(Format('Deleted movie %s', [Movies[I]]));
end
else
begin
MsgBox(Format('Error deleting %s', [Movies[I]]), mbError, MB_OK);
end;
end;
end;
MsgBox(Format('Deleted %d movies', [Deleted]), mbInformation, MB_OK);
Result := False;
end;
end;
finally
Form.Free();
end;
end;
end;