Inno Setup 仅卸载部分组件
Inno Setup Uninstall some components only
对于安装在同一文件夹中的每个不同零售产品,我有一个通用应用程序(如媒体播放器),即
C:\program files\myapp
并且不同的内容(如电影)都安装在同一个文件夹中
C:\program files\myapp\movies
对于每个单独的安装(单独的零售产品),我只是创建一个快捷方式来打开具有特定内容的应用程序,如 mediaplayer -f movie1.mp4
,但它可以打开同一环境中的所有其他内容。
我的问题是卸载。 Inno Setup 不支持组件 selection 卸载。
我的策略(在我当时的想法中)是向用户呈现自定义表单以 select 要卸载的内容。例如。
[X] Main Application
[X] Movie1 Full Title Description
[X] Movie2 Full Title Description
[X] Movie3 Full Title Description
通过这种方式,通用卸载将适用于每个单独的零售安装。
问题:
- 如何创建这样的表单
- 如何扫描公共共享文件夹,即本示例中的
movies
以查找所有已安装的内容,即 movie1.mp4
、movie2.mp4
、.....
- 如何打开和读取每部电影的 header 以读取一些数据,如完整标题,以便在卸载过程中显示它而不是文件名。
我以前在DOS时代写Pascal代码,现在我是C++/MFC程序员
有什么想法、建议、策略吗?
此致。
Inno Setup 不支持部分卸载。
卸载完成后,您的整个应用程序及其所有已安装的组件(电影)都将被删除。
您可以做的是在 InitializeUninstall
中显示带有电影列表的自定义表单。如果用户选择仅卸载(一些)电影,而不是整个应用程序(查看器),您可以使用自己的代码删除电影并中止卸载(通过从 InitializeUninstall
返回 False
)。如果用户选择卸载所有东西,你让卸载完成。
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;
对于安装在同一文件夹中的每个不同零售产品,我有一个通用应用程序(如媒体播放器),即
C:\program files\myapp
并且不同的内容(如电影)都安装在同一个文件夹中
C:\program files\myapp\movies
对于每个单独的安装(单独的零售产品),我只是创建一个快捷方式来打开具有特定内容的应用程序,如 mediaplayer -f movie1.mp4
,但它可以打开同一环境中的所有其他内容。
我的问题是卸载。 Inno Setup 不支持组件 selection 卸载。
我的策略(在我当时的想法中)是向用户呈现自定义表单以 select 要卸载的内容。例如。
[X] Main Application
[X] Movie1 Full Title Description
[X] Movie2 Full Title Description
[X] Movie3 Full Title Description
通过这种方式,通用卸载将适用于每个单独的零售安装。
问题:
- 如何创建这样的表单
- 如何扫描公共共享文件夹,即本示例中的
movies
以查找所有已安装的内容,即movie1.mp4
、movie2.mp4
、..... - 如何打开和读取每部电影的 header 以读取一些数据,如完整标题,以便在卸载过程中显示它而不是文件名。
我以前在DOS时代写Pascal代码,现在我是C++/MFC程序员
有什么想法、建议、策略吗?
此致。
Inno Setup 不支持部分卸载。
卸载完成后,您的整个应用程序及其所有已安装的组件(电影)都将被删除。
您可以做的是在 InitializeUninstall
中显示带有电影列表的自定义表单。如果用户选择仅卸载(一些)电影,而不是整个应用程序(查看器),您可以使用自己的代码删除电影并中止卸载(通过从 InitializeUninstall
返回 False
)。如果用户选择卸载所有东西,你让卸载完成。
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;