2011-09-14 48 views
5

我需要在安装过程中询问用户密码,然后将其用作安装后运行的命令的一部分。我正在使用自定义页面来执行此操作,并且工作正常。自定义卸载页面(不是MsgBox)

我还需要在卸载过程中提出相同的问题,这是卸载后运行的命令的一部分。

我检查了帮助,并且似乎没有用于卸载的PageID,我可以在我的CreateInputQuery函数中使用它。如果页面显示在卸载的开始,中间或结束处,只要显示该页面,我并不特别介意。

我不想使用MsgBox进行卸载,因为我想要标准页面的外观。

有关如何实现此目的的任何提示?

+0

相关:[上卸载向导页面 - jrsoftware.innosetup Newsgr oups](http://news.jrsoftware.org/read/article.php?id=97991&group=jrsoftware.innosetup#97991) – hakre

回答

2

Inno目前不支持卸载过程中的向导页面。您将需要使用Forms来代替。

+0

我想我也得出了同样的结论。最大的问题是所有的PageID都适用于INSTALL而不是UNINSTALL。 – eyoopmeduck

+0

这不是最大的问题,因为卸载与安装程序没有相同的向导模型。 – Deanna

+0

您实际上可以在卸载表单中实现页面。看到我的回答:https://stackoverflow.com/q/7415457/850848#42550055 –

2

我使用InnoSetup 5.4.2,并在文档中有几个Uninstall Event Functions包括: 程序CurUninstallStepChanged(CurUninstallStep:TUninstallStep);

您应该可以在[code]部分中创建一个输入页面。

+0

我也在使用这个版本。对不起,应该在原始问题中提到这一点。 因此,我不是在InitializeWizard过程中定义对话框(以及它适合页面序列的位置),而是使用CreateCustomForm手动对其进行编码。我认为CodeClasses.iss示例可以提供帮助。 感谢您的建议 - 我会给它一个去... – eyoopmeduck

5

幸运的是,Inno Setup提供了足够的能力来构建自己的窗体,因此您可以模仿任何其他模式窗体上卸载窗体的页面。 这是我设法创造的。该表格的尺寸为UninstallForm,包含TNewNotebook控件和按钮以在页面之间跳转并取消对话框。

demo

const 
    ControlGap = 5; // determined empirically 

// Set Back/Next buttons state according to current selected notebook page 
procedure UpdateButtonsState(Form: TSetupForm); 
var 
    Notebook: TNewNotebook; 
    BtnBack, BtnNext: TButton; 
begin 
    Notebook := TNewNotebook(Form.FindComponent('Notebook')); 
    BtnBack := TButton(Form.FindComponent('BtnBack')); 
    BtnNext := TButton(Form.FindComponent('BtnNext')); 

    // Update buttons state 
    BtnBack.Enabled := (Notebook.ActivePage <> Notebook.Pages[0]); 
    if Notebook.ActivePage <> Notebook.Pages[Notebook.PageCount - 1] then 
    begin 
    BtnNext.Caption := SetupMessage(msgButtonNext) 
    BtnNext.ModalResult := mrNone; 
    end 
    else 
    begin 
    BtnNext.Caption := SetupMessage(msgButtonFinish); 
    BtnNext.ModalResult := mrYes; 
    end; 
end; 

// Change notebook page 
procedure BtnPageChangeClick(Sender: TObject); 
var 
    NextPage: TNewNotebookPage; 
    Notebook: TNewNotebook; 
    Form: TWinControl; 
    Button, BtnBack, BtnNext: TButton; 
begin 
    Button := TButton(Sender); 
    Form := Button; 
    while not (Form is TSetupForm) do 
    Form := Form.Parent; 
    Notebook := TNewNotebook(Form.FindComponent('Notebook')); 
    BtnBack := TButton(Form.FindComponent('BtnBack')); 
    BtnNext := TButton(Form.FindComponent('BtnNext')); 

    // Avoid cycled style of Notebook's page looping 
    if (Button = BtnBack) and (Notebook.ActivePage = Notebook.Pages[0]) then 
    NextPage := nil 
    else 
    if (Button = BtnNext) and (Notebook.ActivePage = Notebook.Pages[Notebook.PageCount - 1]) then 
    NextPage := nil 
    else 
    NextPage := Notebook.FindNextPage(Notebook.ActivePage, Button = BtnNext); 
    Notebook.ActivePage := NextPage; 

    UpdateButtonsState(TSetupForm(Form)); 
end; 

// Add a new page to notebook and return it 
function AddPage(NotebookForm: TSetupForm): TNewNotebookPage; 
var 
    Notebook: TNewNotebook; 
begin 
    Notebook := TNewNotebook(NotebookForm.FindComponent('Notebook')); 
    Result := TNewNotebookPage.Create(Notebook); 
    Result.Notebook:=Notebook; 
    Result.Parent:=Notebook; 
    Result.Align := alClient; 
    if Notebook.ActivePage = nil then 
    Notebook.ActivePage := Result; 
    UpdateButtonsState(NotebookForm); 
end; 

// Create a form with notebook and 3 buttons: Back, Next, Cancel 
function CreateNotebookForm: TSetupForm; 
var 
    Notebook: TNewNotebook; 
    NotebookPage: TNewNotebookPage; 
    Pan: TPanel; 
    TmpLabel: TLabel; 
    MaxWidth, i: Integer; 
    BtnBack, BtnNext, BtnCancel: TButton; 
    BtnLabelMsgIDs: array of TSetupMessageID; 
begin 
    Result := CreateCustomForm; 
    Result.SetBounds(0, 0, UninstallProgressForm.Width, UninstallProgressForm.Height); 
    Result.Position := poOwnerFormCenter; 

    Notebook := TNewNotebook.Create(Result); 
    Notebook.Parent := Result; 
    Notebook.Name := 'Notebook'; // will be used for searching 
    Notebook.Align := alClient; 

    Pan := TPanel.Create(Result); 
    Pan.Parent := Notebook; 
    Pan.Caption := ''; 
    Pan.Align := alBottom; 

    // Create buttons 

    BtnNext := TNewButton.Create(Result); 
    with BtnNext do 
    begin 
    Parent := Pan; 
    Name := 'BtnNext'; // will be used for searching 
    Caption := SetupMessage(msgButtonNext); 
    OnClick := @BtnPageChangeClick; 
    ParentFont := True; 
    end; 

    BtnBack := TNewButton.Create(Result); 
    with BtnBack do 
    begin 
    Parent := Pan; 
    Caption := SetupMessage(msgButtonBack); 
    Name := 'BtnBack'; // will be used for searching 
    OnClick := @BtnPageChangeClick; 
    ParentFont := True; 
    end; 

    BtnCancel := TNewButton.Create(Result); 
    with BtnCancel do 
    begin 
    Parent := Pan; 
    Name := 'BtnCancel'; // will be used for searching 
    Caption := SetupMessage(msgButtonCancel); 
    ModalResult := mrCancel; 
    Cancel := True; 
    ParentFont := True; 
    end; 

    // Determine dimensions of buttons. Should use TCanvas.TextWidth here 
    // but it doesn't allow Font property assignment :(

    TmpLabel := TLabel.Create(Result); 
    with TmpLabel do 
    begin 
    Left := 0; 
    Top := 0; 
    Parent := Pan; 
    ParentFont := True; 
    Visible := False; 
    WordWrap := False; 
    Autosize := True; 
    end; 

    // Determine max label width among these labels: Back, Next, Cancel, Finish 
    SetArrayLength(BtnLabelMsgIDs, 4); 
    BtnLabelMsgIDs[0] := msgButtonBack; 
    BtnLabelMsgIDs[1] := msgButtonNext; 
    BtnLabelMsgIDs[2] := msgButtonCancel; 
    BtnLabelMsgIDs[3] := msgButtonFinish; 
    MaxWidth := 0; 
    for i := Low(BtnLabelMsgIDs) to High(BtnLabelMsgIDs) do 
    begin 
    TmpLabel.Caption := SetupMessage(BtnLabelMsgIDs[i]) + 'WWW'; // Add letters for surrounding spaces 
    if MaxWidth < TmpLabel.Width then 
     MaxWidth := TmpLabel.Width; 
    end; 

    TmpLabel.Caption := 'Yy'; // Determine height 

    // Assign sizes and positions 
    Pan.ClientHeight := TmpLabel.Height*4; 

    with BtnBack do 
    begin 
    Width := MaxWidth; 
    Height := TmpLabel.Height*2; 
    Left := Parent.ClientWidth - 3*(MaxWidth + ScaleX(ControlGap)); 
    Top := (Parent.ClientHeight - Height) div 2; 
    end; 
    with BtnNext do 
    begin 
    Width := MaxWidth; 
    Height := TmpLabel.Height*2; 
    Left := Parent.ClientWidth - 2*(MaxWidth + ScaleX(ControlGap)); 
    Top := (Parent.ClientHeight - Height) div 2; 
    end; 
    with BtnCancel do 
    begin 
    Width := MaxWidth; 
    Height := TmpLabel.Height*2; 
    Left := Parent.ClientWidth - 1*(MaxWidth + ScaleX(ControlGap)); 
    Top := (Parent.ClientHeight - Height) div 2; 
    end; 
end; 

用法是一样

// UninstallProgressForm is about to be shown 
// Show modal dialog which allows to select additional components to uninstall 
procedure InitializeUninstallProgressForm; 
var 
    Form: TSetupForm; 
    i: Integer; 
    NotebookPage: TNewNotebookPage; 
    ModResult: Integer; 
begin 
    Form := CreateNotebookForm; 
    for i := 1 to 4 do 
    begin 
    NotebookPage := AddPage(Form); 
    with NotebookPage do 
    begin 
     Color := clWindow; 
     with TLabel.Create(Form) do 
     begin 
     Parent := NotebookPage; 
     SetBounds(0, 0, 50, 30); 
     Autosize := true; 
     Font.Size := 14; 
     Caption := 'Label ' + IntToStr(i); 
     end; 
    end; 
    end; 

    ModResult := Form.ShowModal; 
    if ModResult = mrYes then 
    MsgBox('Continuing uninstall', mbInformation, MB_OK) 
    else 
    begin 
    MsgBox('Cancelled', mbInformation, MB_OK); 
    Abort; 
    end; 

    ... 
end; 
+0

有趣的想法!只是,如果你可以用这种方法拦截卸载过程,那么嵌入就不会更好了,比如说'TPanel'延伸到'UninstallProgressForm'的客户区域,而不是在UninstallProgressForm之上放置另一个表单?你有没有两个单独的(可移动的)形式的代码? – TLama

+0

@TLama当然,这是我尝试的第一件事,但不幸的是,这将无法正常工作。显示UninstallForm后,卸载程序代码无条件地进一步发挥作用,无论我们的操作如何。所以看来,目前侵入卸载过程的唯一方式是模式形式:( – Fr0sT

5

您可以修改卸载形式表现得像安装形式(与页和下一页/后退按钮)。

InitializeUninstallProgressForm

  • 创建新的页面,并将其插入到UninstallProgressForm.InnerNotebook(或.OuterNotebook)。
  • 实施“下一步”和“后退”按钮。
  • 您也可以使“取消”按钮工作。
  • 使用UninstallProgressForm.ShowModal运行窗体的模态循环。
  • 只有在模态循环退出后,恢复表单的原始布局并继续卸载。
[Code] 

var 
    UninstallFirstPage: TNewNotebookPage; 
    UninstallSecondPage: TNewNotebookPage; 
    UninstallBackButton: TNewButton; 
    UninstallNextButton: TNewButton; 

procedure UpdateUninstallWizard; 
begin 
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallFirstPage then 
    begin 
    UninstallProgressForm.PageNameLabel.Caption := 'First uninstall wizard page'; 
    UninstallProgressForm.PageDescriptionLabel.Caption := 
     'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'; 
    end 
    else 
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then 
    begin 
    UninstallProgressForm.PageNameLabel.Caption := 'Second uninstall wizard page'; 
    UninstallProgressForm.PageDescriptionLabel.Caption := 
     'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'; 
    end; 

    UninstallBackButton.Visible := 
    (UninstallProgressForm.InnerNotebook.ActivePage <> UninstallFirstPage); 

    if UninstallProgressForm.InnerNotebook.ActivePage <> UninstallSecondPage then 
    begin 
    UninstallNextButton.Caption := SetupMessage(msgButtonNext); 
    UninstallNextButton.ModalResult := mrNone; 
    end 
    else 
    begin 
    UninstallNextButton.Caption := 'Uninstall'; 
    { Make the "Uninstall" button break the ShowModal loop } 
    UninstallNextButton.ModalResult := mrOK; 
    end; 
end; 

procedure UninstallNextButtonClick(Sender: TObject); 
begin 
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then 
    begin 
    UninstallNextButton.Visible := False; 
    UninstallBackButton.Visible := False; 
    end 
    else 
    begin 
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallFirstPage then 
    begin 
     UninstallProgressForm.InnerNotebook.ActivePage := UninstallSecondPage; 
    end; 
    UpdateUninstallWizard; 
    end; 
end; 

procedure UninstallBackButtonClick(Sender: TObject); 
begin 
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then 
    begin 
    UninstallProgressForm.InnerNotebook.ActivePage := UninstallFirstPage; 
    end; 
    UpdateUninstallWizard; 
end; 

procedure InitializeUninstallProgressForm(); 
var 
    PageText: TNewStaticText; 
    PageNameLabel: string; 
    PageDescriptionLabel: string; 
    CancelButtonEnabled: Boolean; 
    CancelButtonModalResult: Integer; 
begin 
    if not UninstallSilent then 
    begin 
    { Create the first page and make it active } 
    UninstallFirstPage := TNewNotebookPage.Create(UninstallProgressForm); 
    UninstallFirstPage.Notebook := UninstallProgressForm.InnerNotebook; 
    UninstallFirstPage.Parent := UninstallProgressForm.InnerNotebook; 
    UninstallFirstPage.Align := alClient; 

    PageText := TNewStaticText.Create(UninstallProgressForm); 
    PageText.Parent := UninstallFirstPage; 
    PageText.Top := UninstallProgressForm.StatusLabel.Top; 
    PageText.Left := UninstallProgressForm.StatusLabel.Left; 
    PageText.Width := UninstallProgressForm.StatusLabel.Width; 
    PageText.Height := UninstallProgressForm.StatusLabel.Height; 
    PageText.AutoSize := False; 
    PageText.ShowAccelChar := False; 
    PageText.Caption := 'Press Next to proceeed with uninstallation.'; 

    UninstallProgressForm.InnerNotebook.ActivePage := UninstallFirstPage; 

    PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; 
    PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption; 

    { Create the second page } 

    UninstallSecondPage := TNewNotebookPage.Create(UninstallProgressForm); 
    UninstallSecondPage.Notebook := UninstallProgressForm.InnerNotebook; 
    UninstallSecondPage.Parent := UninstallProgressForm.InnerNotebook; 
    UninstallSecondPage.Align := alClient; 

    PageText := TNewStaticText.Create(UninstallProgressForm); 
    PageText.Parent := UninstallSecondPage; 
    PageText.Top := UninstallProgressForm.StatusLabel.Top; 
    PageText.Left := UninstallProgressForm.StatusLabel.Left; 
    PageText.Width := UninstallProgressForm.StatusLabel.Width; 
    PageText.Height := UninstallProgressForm.StatusLabel.Height; 
    PageText.AutoSize := False; 
    PageText.ShowAccelChar := False; 
    PageText.Caption := 'Press Uninstall to proceeed with uninstallation.'; 

    UninstallNextButton := TNewButton.Create(UninstallProgressForm); 
    UninstallNextButton.Parent := UninstallProgressForm; 
    UninstallNextButton.Left := 
     UninstallProgressForm.CancelButton.Left - 
     UninstallProgressForm.CancelButton.Width - 
     ScaleX(10); 
    UninstallNextButton.Top := UninstallProgressForm.CancelButton.Top; 
    UninstallNextButton.Width := UninstallProgressForm.CancelButton.Width; 
    UninstallNextButton.Height := UninstallProgressForm.CancelButton.Height; 
    UninstallNextButton.OnClick := @UninstallNextButtonClick; 

    UninstallBackButton := TNewButton.Create(UninstallProgressForm); 
    UninstallBackButton.Parent := UninstallProgressForm; 
    UninstallBackButton.Left := 
     UninstallNextButton.Left - UninstallNextButton.Width - 
     ScaleX(10); 
    UninstallBackButton.Top := UninstallProgressForm.CancelButton.Top; 
    UninstallBackButton.Width := UninstallProgressForm.CancelButton.Width; 
    UninstallBackButton.Height := UninstallProgressForm.CancelButton.Height; 
    UninstallBackButton.Caption := SetupMessage(msgButtonBack); 
    UninstallBackButton.OnClick := @UninstallBackButtonClick; 
    UninstallBackButton.TabOrder := UninstallProgressForm.CancelButton.TabOrder; 

    UninstallNextButton.TabOrder := UninstallBackButton.TabOrder + 1; 

    UninstallProgressForm.CancelButton.TabOrder := UninstallNextButton.TabOrder + 1; 

    { Run our wizard pages } 
    UpdateUninstallWizard; 
    CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled 
    UninstallProgressForm.CancelButton.Enabled := True; 
    CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult; 
    UninstallProgressForm.CancelButton.ModalResult := mrCancel; 

    if UninstallProgressForm.ShowModal = mrCancel then Abort; 

    { Restore the standard page payout } 
    UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled; 
    UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult; 

    UninstallProgressForm.PageNameLabel.Caption := PageNameLabel; 
    UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel; 

    UninstallProgressForm.InnerNotebook.ActivePage := 
     UninstallProgressForm.InstallingPage; 
    end; 
end; 

First page

Second page

Uninstalling


参见Inno Setup - How to create a OuterNotebook/welcome page in the uninstaller?

+0

是否可以轻松地转换(隐藏,移动等)第一页以匹配安装程序的欢迎页面?(我正在尝试但我 –

+0

欢迎页面是“OutterNotebook”的页面,而不是“InnerNotebook”,但是这会使Next/Back按钮的逻辑复杂化 –

+0

当然,欢迎页面是OutterNotebook的页面' - 它覆盖顶部标题,顶部标题('MainPanel')(连同'InnerNotebook')是'OutterNotebook'页面的一部分,称为'InnerPage' - 结构与安装程序和卸载程序相同。在卸载程序中大部分结构都没有使用(因为只有一个页面) - 但它对你来说确实很好,因为你可以在安装程序中轻松实现相同的布局。 –