简体   繁体   English

Inno Setup 只卸载一些组件

[英]Inno Setup Uninstall some components only

I have a common application -like a media player- for each different retail product that is installed in the same folder ie对于安装在同一文件夹中的每个不同的零售产品,我都有一个通用的应用程序——比如媒体播放器——

C:\\program files\\myapp C:\\程序文件\\我的应用程序

and the different content -like movies- are all installed in the same folder并且不同的内容——比如电影——都安装在同一个文件夹中

C:\\program files\\myapp\\movies C:\\程序文件\\我的应用程序\\电影

For each separate installation (separate retail product), I just create a shortcut to open the application with the specific content like mediaplayer -f movie1.mp4 , but it can open all other content from the same environment.对于每个单独的安装(单独的零售产品),我只是创建一个快捷方式来打开具有特定内容的应用程序,例如mediaplayer -f movie1.mp4 ,但它可以打开同一环境中的所有其他内容。

The problem in my case, is the uninstallation.就我而言,问题是卸载。 Inno Setup does not support component selection to uninstall. Inno Setup 不支持组件选择卸载。

My strategy (in my mind at the time) is to present the user a custom form to select the content to uninstall.我的策略(在我当时的想法中)是向用户呈现一个自定义表单来选择要卸载的内容。 For example.例如。

[X] Main Application 
[X] Movie1 Full Title Description 
[X] Movie2 Full Title Description
[X] Movie3 Full Title Description

With that way the common uninstall will work for every separate retail installation.通过这种方式,通用卸载将适用于每个单独的零售安装。

The problems:问题:

  1. How to create such a form如何创建这样的表单
  2. How to scan the common shared folder ie movies for this example to find all installed content ie movie1.mp4 , movie2.mp4 , .....如何扫描此示例的常用共享文件夹 ie movies以查找所有已安装的内容,即movie1.mp4movie2.mp4 ......
  3. How to open and read the header of each movie to read some data like the full title to show it in the uninstallation procedure instead of the filename.如何打开和读取每部电影的标题以读取一些数据,如完整标题,以在卸载过程中显示它而不是文件名。

I used to write Pascal code at the DOS era but I now I am a C++/MFC programmer.我曾经在 DOS 时代编写 Pascal 代码,但现在我是一名 C++/MFC 程序员。

Any ideas, recommendations, strategies?任何想法,建议,策略?

Best regards.最好的问候。

Inno Setup does not support partial uninstallations. Inno Setup 不支持部分卸载。

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 .您可以做的是在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 ).如果用户选择仅卸载(部分)电影,而不是整个应用程序(查看器),您可以使用自己的代码删除电影并中止卸载(通过从InitializeUninstall返回False )。 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;

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM