在卸载结束时显示自定义页面

Display custom page at the end of uninstallation

我正在尝试找到一种在卸载结束时显示 "Uninstall complete" 页面的方法,就像在安装结束时显示 "Installation complete" 页面一样,同时 skip/hide 自动卸载完成msgbox.

我已经尝试过 CreateCustomPage 或其他创建页面函数的方法,但这不起作用,因为我收到一条消息,告诉我在卸载过程中无法调用这些函数...

那么,有没有办法显示(并控制)这样的页面?

还是我必须处理唯一的卸载完成的消息框?

我的第一个目标是在此页面上显示一个复选框,让用户选择打开或不打开尚未卸载的数据文件夹...

您无法更改或添加向导页面of/to 卸载程序 - 不支持 CreateCustomPage()。

但是您可以使用 CreateCustomForm()(而不是 CreateCustomPage)和 ShowModal() 显示自定义表单,并使用 MsgBox() 显示消息框,就像这样

[Code]
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then
  begin
    // this is MsgBox will display after uninstall
    if MsgBox('Go to data folder?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then       
    begin
      // add some code to open the explorer with the folder here
      Exec(ExpandConstant('{win}\explorer.exe'), 'c:\data\folder', '', SW_SHOW, ewNoWait, ResultCode);
    end;
  end;
end;

如果您想显示复选框,CreateCustomForm() 是最佳选择。

你可以尝试像这样的代码:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
DisableProgramGroupPage=yes
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
DirExistsWarning=no             
DisableDirPage=yes                        

[Files]
Source: "MyProg.exe"; DestDir: "{app}"
Source: "MyProg.chm"; DestDir: "{app}"
Source: "Readme.txt"; DestDir: "{app}";

#define AppName  SetupSetting('AppName')     
#define AppVersion  SetupSetting('AppVersion')
#define AppId  SetupSetting('AppId')             
#if AppId == ""   
  #define AppId AppName
#endif                     

[Code]       
var
  CustomPage: TWizardPage;                                     
  ResultCode:Integer;
  Source, Dest,Uninstall,ParamStr: String;
  CancelPrompt:Boolean;  
procedure CurStepChanged(CurStep: TSetupStep);      
begin
  if CurStep=ssPostInstall then begin
    Source := ExpandConstant('{srcexe}');
    Dest := ExpandConstant('{app}\unins001.exe');               
    Exec('cmd.exe', '/c COPY "'+Source+'" "'+Dest+'"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);    
  end;                                                                                                                                                                                                                      
end;

function IsUnInstall(): Boolean;
begin
  Result := Pos('/CUNINSTALL',UpperCase(GetCmdTail)) > 0;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin                                  
  Result := False;
  if IsUnInstall() then begin
    if PageID <> wpWelcome then     
      case PageID of
        CustomPage.ID:;    
      else Result := True;
    end;
  end;
end;

procedure ExitButton(Sender: TObject);   
begin                   
    CancelPrompt:=False;       
    WizardForm.Close;                                             
    Source := ExpandConstant('{src}');                  
    Exec('cmd.exe', '/C rmdir /S /Q "'+Source+'"', '', SW_HIDE, ewNoWait, ResultCode);    
end;               

procedure CancelButtonClick(PageID: Integer; var Cancel, Confirm: Boolean); 
begin                                           
    Confirm:=CancelPrompt;                                                                                   
end;

function NextButtonClick(PageID: Integer): Boolean;            
begin
  Result := True;             
  if IsUnInstall() then begin   
    if PageID = wpWelcome then begin      
      RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1','UninstallString', Uninstall);
      Exec(RemoveQuotes(Uninstall), ' /RECAll /SILENT' , '', SW_SHOW, ewWaitUntilTerminated, ResultCode);      
    end;
  end;
end;     

function CreatePage(var Page:TWizardPage;PageId:Integer):Integer;    
begin
  Page := CreateCustomPage(PageId, ExpandConstant('AAA'),ExpandConstant('BBB'));           
end;     

procedure CurPageChanged(PageID: Integer);
begin                                       
  if IsUnInstall() then begin   
    if PageID = CustomPage.ID then begin          
      with WizardForm do begin      
        CancelButton.Left:= NextButton.Left;
        CancelButton.Caption:=ExpandConstant('Finish');                                
        CancelButton.OnClick := @ExitButton;
        NextButton.Visible := False;          
        BackButton.Visible := False;          
      end;          
    end;
  end;
end;

procedure InitializeWizard();          
begin
  if IsUnInstall() then
  begin                                        
    CreatePage(CustomPage,wpWelcome);
    with WizardForm do begin      
      WelcomeLabel1.Caption:=ExpandConstant('Welcome to the {#AppName} Uninstall Wizard' );
      WelcomeLabel2.Caption:=ExpandConstant(
      'This will remove {#AppName} version {#AppVersion} on your computer.' +#13+
      ''+#13+
      'It is recommended that you close all other applications before continuing.'+#13+
      ''+#13+
      'Click Next to continue, or Cancel to exit Setup.'
      );
    end;
  end;
end;

function InitializeUninstall(): Boolean;    
begin
  if FileExists(ExpandConstant('{app}\unins001.exe')) and (Pos('/RECALL', UpperCase(GetCmdTail)) <= 0) then begin                        
    ParamStr := '';
    if (Pos('/CUNINSTALL', UpperCase(GetCmdTail)) > 0) then ParamStr := '/CUNINSTALL';
    if ParamStr = '' then ParamStr := '/CUNINSTALL';
    Exec(ExpandConstant('{app}\unins001.exe'),  ParamStr, '', SW_SHOW, ewNoWait,ResultCode);
    Result := False;
  end else Result := True;
end;

我尝试添加一个面板和一个位图来测试我的自定义表单上的这些组件。

没有报错,'BitmapFileName'中的路径没问题,但是面板和位图都没有显示:

procedure FormCheckOuvrirRepDonnees();
var
  Form: TSetupForm;
  OKButton: TNewButton;
  CheckBox: TNewCheckBox;
  Label1: TNewStaticText;
  Label2: TLabel;
  Panel: TPanel;
  BitmapImage: TBitmapImage;
  BitmapFileName: String;
begin
  Form := CreateCustomForm();
  try
    Form.ClientWidth := ScaleX(700);
    Form.ClientHeight := ScaleY(500);
    Form.Caption := ExpandConstant('{#MyAppName} {#MyAppVersion}');
    //Form.CenterInsideControl(WizardForm, False);
    Form.Center;

    Label1 := TNewStaticText.Create(Form);
    Label1.Parent := Form;
    //Label1.Width := Form.ClientWidth - ScaleX(2 * 10);
    Label1.AutoSize := true;
    Label1.Height := ScaleY(50);
    Label1.Left := ScaleX(325);
    Label1.Top := ScaleY(10);
    Label1.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');

    Label2 := TLabel.Create(Form);
    Label2.Parent := Form;
    //Label1.Width := Form.ClientWidth - ScaleX(2 * 10);
    Label2.AutoSize := true;
    Label2.Height := ScaleY(50);
    Label2.Left := ScaleX(325);
    Label2.Top := ScaleY(60);
    Label2.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');

    Panel := TPanel.Create(Form);
    Panel.Top := ScaleY(120);
    Panel.Width := Form.ClientWidth - ScaleX(2 * 10);
    Panel.Left := ScaleX(325);
    Panel.Height := ScaleY(50);
    Panel.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonneeDescription1}');
    Panel.Color := clWindow;
    //Panel.ParentBackground := False;
    //Panel.Parent := Form.Surface;

    BitmapImage := TBitmapImage.Create(Form);
    BitmapImage.Left := Form.left;
    BitmapImage.top := Form.top;
    BitmapImage.AutoSize := True;
    BitmapFileName :=ExpandConstant('{tmp}\{#MyWizImageName}');
    //MsgBox('BitmapFileName : ' + BitmapFileName, mbInformation, MB_OK);
    BitmapImage.Bitmap.LoadFromFile(BitmapFileName);
    //BitmapImage.Cursor := crHand;

    CheckBox := TNewCheckBox.Create(Form);
    CheckBox.Parent := Form;
    CheckBox.Width := Form.ClientWidth - ScaleX(2 * 10);
    CheckBox.Height := ScaleY(17);
    CheckBox.Left := ScaleX(325);
    CheckBox.Top := ScaleY(200);
    CheckBox.Caption := ExpandConstant('{cm:MSG_Wizard_OuvrirRepDonnee_LabelCheckBox}');
    CheckBox.Checked := False;

    OKButton := TNewButton.Create(Form);
    OKButton.Parent := Form;
    OKButton.Width := ScaleX(75);
    OKButton.Height := ScaleY(23);
    OKButton.Left := ((Form.ClientWidth - OKButton.Width)/2);
    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 := ScaleX(75);
    //CancelButton.Height := ScaleY(23);
    //CancelButton.Left := Form.ClientWidth - ScaleX(75 + 10);
    //CancelButton.Top := Form.ClientHeight - ScaleY(23 + 10);
    //CancelButton.Caption := 'Cancel';
    //CancelButton.ModalResult := mrCancel;
    //CancelButton.Cancel := True;

    Form.ActiveControl := OKButton;

    if Form.ShowModal = mrOk then begin
      if CheckBox.Checked = true then begin
        CheckOuvrirRepDonnees := true;
      end;
    end;

  finally
    Form.Free();
  end;
end;

有人知道那里出了什么问题吗?