Inno Setup仅卸载某些组件 [英] Inno Setup Uninstall some components only

查看:129
本文介绍了Inno Setup仅卸载某些组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

C:\program files\myapp

和不同的内容(例如电影)都安装在同一文件夹中

and the different content -like movies- are all installed in the same folder

C:\ program files \ myapp \ movies

C:\program files\myapp\movies

对于每个单独的安装(单独的零售产品),我只是创建一个快捷方式来打开具有特定内容(例如mediaplayer -f movie1.mp4)的应用程序,但是它可以打开同一环境中的所有其他内容.

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.

我的问题是卸载. Inno Setup不支持要卸载的组件选择.

The problem in my case, is the uninstallation. Inno Setup does not support component selection to uninstall.

我当时的策略是向用户提供一个自定义表单,以选择要卸载的内容.例如.

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.

问题:

  1. 如何创建这样的表格
  2. 在本示例中,如何扫描公用共享文件夹(即movies)以查找所有已安装的内容,即movie1.mp4movie2.mp4,.....
  3. 如何打开和读取每部电影的标题以读取一些数据(如完整标题)以在卸载过程中显示它而不是文件名.
  1. How to create such a form
  2. How to scan the common shared folder i.e. movies for this example to find all installed content i.e. movie1.mp4, movie2.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.

我曾经在DOS时代写过Pascal代码,但现在我是C ++/MFC程序员.

I used to write Pascal code at the DOS era but I now I am a C++/MFC programmer.

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

Any ideas, recommendations, strategies?

最诚挚的问候.

推荐答案

Inno Setup不支持部分卸载.

Inno Setup does not support partial uninstallations.

一旦卸载完成,带有所有已安装组件(电影)的整个应用程序将被删除.

Once the uninstallation completes, your whole application with all installed components (movies) will be deleted.

您可以做的是在InitializeUninstall中的电影列表中显示自定义表单.如果用户选择仅卸载(某些)电影,而不是整个应用程序(查看器),则可以使用自己的代码删除电影并中止卸载(通过从InitializeUninstall返回False).如果用户选择卸载所有内容,则让卸载完成.

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;

这篇关于Inno Setup仅卸载某些组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆