2017-07-12 76 views
1

我試圖在將PrepareToInstall頁面上的進度條和標籤複製(遷移)到以前的安裝到新位置時顯示。我正在使用Martin Prikryl的DirectoryCopy程序的稍微修改版本,並按預期工作;將文件和目錄複製到新位置,並將操作記錄到文件中。Inno Setup在PrepareToInstall頁面上顯示目錄複製進度條和標籤

但是,在複製文件時,如果有很多文件(我測試了2,500個文件,總共大約1.2GB,這可能是一個相當長的運行操作),GUI不更新並顯示凍結,而不顯示任何我的自定義控件(即沒有進度條和沒有進度標籤)。我設法通過調用RefreshUpdate來強制顯示這些顯示,但進度條沒有動畫效果,並且在複製操作完成時,整個GUI顯示無響應。我認爲Inno Setup僅支持single-threaded operations is maybe what is causing the GUI to freeze and not update這一事實。有沒有辦法複製文件並同時更新GUI?

[Code] 
var 
    PrepareToInstallLabel: TNewStaticText; 
    PrepareToInstallProgressBar: TNewProgressBar; 

//Slightly modified Public Domain code to copy a directory recursively and update PrepareToInstall label progress 
//Contributed by Martin Prikryl on Stack Overflow 
procedure DirCopy(strSourcePath, strDestPath: String); 
var 
    FindRec: TFindRec; 
    strSourceFilePath, strDestFilePath: String; 
begin 
    if FindFirst(strSourcePath + '\*', FindRec) then 
    begin 
     try 
     repeat 
      if (FindRec.Name <> '.') and (FindRec.Name <> '..') then 
      begin 
       strSourceFilePath := strSourcePath + '\' + FindRec.Name; 
       strDestFilePath := strDestPath + '\' + FindRec.Name; 
       if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then 
       begin 
        PrepareToInstallLabel.Caption := 'Copying ' + strSourceFilePath + '...'; 
        if FileCopy(strSourceFilePath, strDestFilePath, False) then 
        begin 
         Log(Format('Copied %s to %s', [strSourceFilePath, strDestFilePath])); 
        end 
        else 
        begin 
         SuppressibleMsgBox(Format('Failed to copy %s to %s', [strSourceFilePath, strDestFilePath]), 
         mbError, MB_OK, IDOK); 
        end; 
       end 
       else 
       begin 
        if CreateDir(strDestFilePath) then 
        begin 
         Log(Format('Created %s', [strDestFilePath])); 
         DirCopy(strSourceFilePath, strDestFilePath); 
        end 
        else 
        begin 
         SuppressibleMsgBox(Format('Failed to create %s', [strDestFilePath]), 
         mbError, MB_OK, IDOK); 
        end; 
       end; 
      end; 
     until 
      not FindNext(FindRec); 
     finally 
     FindClose(FindRec); 
     end; 
    end 
    else 
    begin 
     SuppressibleMsgBox(Format('Failed to list %s', [strSourcePath]), 
     mbError, MB_OK, IDOK); 
    end; 
end; 

//Show PrepareToInstall page GUI controls 
procedure ShowPrepareToInstallGuiControls(); 
begin 
    PrepareToInstallProgressBar.Visible := True; 
    PrepareToInstallLabel.Visible := True; 
end; 

//Update PrepareToInstall page GUI controls; note this procedure should not be needed 
procedure UpdatePrepareToInstallGuiControls(); 
begin 
//Both lines below seem to be needed to force the Cancel button to disable, 
//despite already disabling the button at the beginning of the PrepareToInstall event 
    WizardForm.CancelButton.Enabled := False; 
    WizardForm.CancelButton.Refresh; 
//Both lines below seem to be needed to force display of the progress bar and label, 
//despite already showing them in the PrepareToInstall event; without them no controls are shown on the page. 
    PrepareToInstallLabel.Update; 
    PrepareToInstallProgressBar.Update; 
end; 

//Hide PrepareToInstall page GUI controls 
procedure HidePrepareToInstallGuiControls(); 
begin 
    PrepareToInstallProgressBar.Visible := False; 
    PrepareToInstallLabel.Visible := False; 
end; 

function PrepareToInstall(var NeedsRestart: Boolean): String; 
begin 
    WizardForm.CancelButton.Enabled := False; 
//Migrate installation 
    if IsMigration then 
    begin 
     ShowPrepareToInstallGuiControls; 
     PrepareToInstallLabel.Caption := 'Migrating installation...'; 
     UpdatePrepareToInstallGuiControls; 
     Log('Installation migration started.'); 
     ForceDirectories(ExpandConstant('{app}\FolderToMigrate')); 
     DirCopy(strExistingInstallPath + '\Database', ExpandConstant('{app}\FolderToMigrate')); 
     Log('Installation migration finished.'); 
    end; 
    HidePrepareToInstallGuiControls; 
end; 

procedure InitializeWizard(); 
//Define the label for the Preparing to Install page 
    PrepareToInstallLabel := TNewStaticText.Create(WizardForm); 
    with PrepareToInstallLabel do 
    begin 
     Visible := False; 
     Parent := WizardForm.PreparingPage; 
     Left := WizardForm.StatusLabel.Left; 
     Top := WizardForm.StatusLabel.Top; 
    end; 
//Define Progress Bar for the Preparing to Install Page 
    PrepareToInstallProgressBar := TNewProgressBar.Create(WizardForm); 
    with PrepareToInstallProgressBar do 
    begin 
     Visible := False; 
     Parent := WizardForm.PreparingPage; 
     Left := WizardForm.ProgressGauge.Left; 
     Top := WizardForm.ProgressGauge.Top; 
     Width := WizardForm.ProgressGauge.Width; 
     Height := WizardForm.ProgressGauge.Height; 
     Min := 0; 
     Max := 100; 
     Style := npbstMarquee; 
    end; 
end; 

更新:我添加WizardForm.Refresh;PrepareToInstallLabel.Caption := 'Copying ' + strSourceFilePath + '...';下,這似乎強制標籤以更新,但仍然沒有進度條動畫。此外,在複製每個文件後,調用WizardForm.Refresh幾千次似乎並不是特別有效。

回答

相關問題