Inno Setup-如何在解压缩页面添加取消按钮? [英] Inno Setup - How to add cancel button to decompressing page?

查看:90
本文介绍了Inno Setup-如何在解压缩页面添加取消按钮?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码:






代码提取了一个单独的.arc文件。如果要将存档嵌入到安装程序中,则可以使用

  [文件] 
来源:{#ArcArchive }; DestDir: {tmp};标志:nocompression deleteafterinstall

并从 {tmp}中提取归档文件

  ArcArchivePath:= ExpandConstant('{tmp} \ {# ArcArchive}'); 






请注意 unarc ISFreeArcExtract v.4.0.rar 中的.dll 似乎不支持受密码保护的存档。 ISFreeArcExtract v.4.2.rar 的版本可以,但是我不知道值得信赖的下载链接。






如果要提取多个存档,请参见 Inno Setup-如何将多个arc文件添加到解压缩?


I am using this code: How to add .arc decompression to Inno Setup? (answer of Martin Prikryl). I want to add a cancel button at decompressing page and active this page for others functions (when the decompression is active, this page is inactive and, for example, i can not press on/off button of my music implementation).

How to add a cancel button to decompression page? and how to active this page for others functions?

解决方案

I have reimplemented the solution from How to add .arc decompression to Inno Setup? using unarc.dll (from FreeArc+InnoSetup package ISFreeArcExtract v.4.0.rar).

It greatly simplifies the code and also makes it easier to add the ability to cancel the decompression.


#define ArcArchive "test.arc"

[Files]
Source: unarc.dll; Flags: dontcopy

[Code]

const
  ArcCancelCode = -10;

function FreeArcExtract(
  Callback: LongWord;
  Cmd1, Cmd2, Cmd3, Cmd4, Cmd5, Cmd6, Cmd7, Cmd8, Cmd9, Cmd10: PAnsiChar): Integer;
  external 'FreeArcExtract@files:unarc.dll cdecl';

const
  CP_UTF8 = 65001;

function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD;
  lpWideCharStr: string; cchWideChar: Integer; lpMultiByteStr: AnsiString;
  cchMultiByte: Integer; lpDefaultCharFake: Integer;
  lpUsedDefaultCharFake: Integer): Integer;
  external 'WideCharToMultiByte@kernel32.dll stdcall';

function GetStringAsUtf8(S: string): AnsiString;
var
  Len: Integer;
begin
  Len := WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, 0, 0, 0);
  SetLength(Result, Len);
  WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, Len, 0, 0);
end;

var
  ArcTotalSize: Integer;
  ArcExtracted: Integer;
  ArcCancel: Boolean;
  ArcProgressPage: TOutputProgressWizardPage;

function FreeArcCallback(
  AWhat: PAnsiChar; Int1, Int2: Integer; Str: PAnsiChar): Integer;
var
  What: string;
begin
  What := AWhat;
  if What = 'origsize' then
  begin
    ArcTotalSize := Int1;
    Log(Format('Total size of files to be extracted is %d MB', [ArcTotalSize]));
  end
    else
  if What = 'write' then
  begin
    if ArcTotalSize > 0 then
    begin
      ArcProgressPage.SetProgress(Int1, ArcTotalSize);
    end;
    ArcExtracted := Int1;
  end
    else
  begin
    { Just to pump message queue more often (particularly for 'read' callbacks), }
    { to get more smooth progress bar }
    if (ArcExtracted > 0) and (ArcTotalSize > 0) then
    begin
      ArcProgressPage.SetProgress(ArcExtracted, ArcTotalSize);
    end;
  end;

  if ArcCancel then Result := ArcCancelCode
    else Result := 0;
end;

function FreeArcCmd(
  Cmd1, Cmd2, Cmd3, Cmd4, Cmd5, Cmd6, Cmd7, Cmd8, Cmd9, Cmd10: string): Integer;
begin
  ArcCancel := False;
  try
    Result :=
      FreeArcExtract(
        CreateCallback(@FreeArcCallback),
        GetStringAsUtf8(Cmd1), GetStringAsUtf8(Cmd2), GetStringAsUtf8(Cmd3),
        GetStringAsUtf8(Cmd4), GetStringAsUtf8(Cmd5), GetStringAsUtf8(Cmd6),
        GetStringAsUtf8(Cmd7), GetStringAsUtf8(Cmd8), GetStringAsUtf8(Cmd9),
        GetStringAsUtf8(Cmd10));

    Log(Format('Arc command "%s" result %d', [Cmd1, Result]));
  except
    Result := -63;
  end;
end;

function UnPackArchive(ArchivePath: string; DestPath: string): Integer;
begin
  { Find out length of files to be extracted - origsize }
  Result := FreeArcCmd('l', '--', ArchivePath, '', '', '', '', '', '', '');

  if Result = 0 then
  begin
    { Actually extract }
    Result :=
      FreeArcCmd('x', '-o+', '-dp' + DestPath, '-w' + DestPath, '--', ArchivePath,
                 '', '', '', '');
  end;
end;

procedure UnpackCancelButtonClick(Sender: TObject);
begin
  ArcCancel := True;
end;

procedure ExtractArc;
var
  ArcArchivePath: string;
  UnpackResult: Integer;
  PrevCancelButtonClick: TNotifyEvent;
  Error: string;
begin
  ArcProgressPage :=
    CreateOutputProgressPage('Decompression', 'Decompressing archive...');
  ArcProgressPage.SetProgress(0, 100);
  ArcProgressPage.Show;
  try
    WizardForm.CancelButton.Visible := True;
    WizardForm.CancelButton.Enabled := True;
    PrevCancelButtonClick := WizardForm.CancelButton.OnClick;
    WizardForm.CancelButton.OnClick := @UnpackCancelButtonClick;

    ArcArchivePath := ExpandConstant('{src}\{#ArcArchive}');
    Log(Format('Arc extraction starting - %s', [ArcArchivePath]));

    ArcExtracted := 0;
    UnpackResult := UnPackArchive(ArcArchivePath, ExpandConstant('{app}'));

    if UnpackResult <> 0 then
    begin
      if ArcCancel then
      begin
        Error := 'Extraction cancelled';
      end
        else
      begin
        Error := Format('Extraction failed with code %d', [UnpackResult]);
      end;

      MsgBox(Error, mbError, MB_OK);
    end;
  finally
    Log('Arc extraction cleanup');
    ArcProgressPage.Hide;
    WizardForm.CancelButton.OnClick := PrevCancelButtonClick;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    ExtractArc;
  end;
end;


For CreateCallback function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback function from InnoTools InnoCallback library.



The code extracts a separate .arc file. If you want to embed the archive to the installer, you can use

[Files]
Source: {#ArcArchive}; DestDir: "{tmp}"; Flags: nocompression deleteafterinstall

And extract the archive from the {tmp}:

ArcArchivePath := ExpandConstant('{tmp}\{#ArcArchive}');


Note that the unarc.dll from ISFreeArcExtract v.4.0.rar does not seem to support password protected archives. The version from ISFreeArcExtract v.4.2.rar does, but I'm not aware of trustworthy download link.


If you want to extract multiple archives, see Inno Setup - How to add multiple arc files to decompress?

这篇关于Inno Setup-如何在解压缩页面添加取消按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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