【问题标题】:Inno Setup Uninstall some components onlyInno Setup 仅卸载某些组件
【发布时间】:2016-09-27 04:53:10
【问题描述】:

对于安装在同一文件夹中的每个不同零售产品,我都有一个通用应用程序(例如媒体播放器),即

C:\程序文件\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

这样,通用卸载将适用于每个单独的零售安装。

问题:

  1. 如何创建这样的表单
  2. 如何扫描公共共享文件夹,即movies,以查找所有已安装的内容,即movie1.mp4movie2.mp4、.....
  3. 如何打开并读取每部电影的标题以读取完整标题等数据,以便在卸载过程中显示它而不是文件名。

我曾经在 DOS 时代编写 Pascal 代码,但我现在是一名 C++/MFC 程序员。

有什么想法、建议、策略吗?

最好的问候。

【问题讨论】:

    标签: inno-setup uninstallation pascalscript


    【解决方案1】:

    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;
    

    【讨论】:

      猜你喜欢
      • 2014-07-08
      • 2018-05-04
      • 1970-01-01
      • 2011-09-18
      • 2011-12-06
      • 2013-03-28
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多