我有一个常见的应用程序 - 比如媒体播放器 - 用于安装在同一文件夹中的每个不同的零售产品,即
C:\ program files \ myapp
和不同类似内容的电影都安装在同一个文件夹中
C:\ program files \ myapp \ movies
对于每个单独的安装(单独的零售产品),我只是创建一个快捷方式来打开具有mediaplayer -f movie1.mp4
等特定内容的应用程序,但它可以打开来自同一环境的所有其他内容。
在我的情况下,问题是卸载。 Inno Setup不支持卸载组件选择。
我的策略(当时在我看来)是向用户提供一个自定义表单来选择要卸载的内容。例如。
[X] Main Application
[X] Movie1 Full Title Description
[X] Movie2 Full Title Description
[X] Movie3 Full Title Description
通过这种方式,通用卸载将适用于每个单独的零售安装。
movies
以查找所有已安装的内容,例如movie1.mp4
,movie2.mp4
,..... 我曾经在DOS时代编写Pascal代码,但我现在是C ++ / MFC程序员。
任何想法,建议,策略?
最好的问候。
答案 0 :(得分:2)
Inno Setup不支持部分卸载。
卸载完成后,将删除包含所有已安装组件(电影)的整个应用程序。
您可以做的是在InitializeUninstall
中展示带有电影列表的自定义表单。如果用户选择仅卸载(某些)电影,而不是整个应用程序(观看者),则使用您自己的代码删除电影并中止卸载(通过从False
返回InitializeUninstall
)。如果用户选择卸载所有内容,则可以完成卸载。
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;