InnoDependencyInstaller icon indicating copy to clipboard operation
InnoDependencyInstaller copied to clipboard

Introduce a way to specify a custom Execute method to be called when installing a dependency

Open obones opened this issue 4 years ago • 0 comments

This allows for special cases not handled by this project, like decompressing archive files for instance. In our case, we call it like this:

#define Dependency_NoExampleSetup
#define Dependency_CustomExecute "CustomExecute"
#include <..\..\..\External\InnoDependencyInstaller\CodeDependencies.iss>

And we defined the following items that declares a CustomExecute procedure that in turn calls the command line version of 7-zip:

#define protected CurrentFilePath ExtractFilePath(__PATHFILENAME__)

[Files]
Source: "{#CurrentFilePath}\7za.exe"; Flags: dontcopy

[Code]
const
  ERROR_7_ZIP_NO_ERROR = 0;
  ERROR_7_ZIP_WARNING = 1;
  ERROR_7_ZIP_FATAL_ERROR = 2;
  ERROR_7_ZIP_CMD_LINE_ERROR = 7;
  ERROR_7_ZIP_NOT_ENOUGH_MEMORY = 8;
  ERROR_7_ZIP_USER_ABORT = 255;

function Decompress(const FileName, Parameters: string; var ResultCode: Integer): Boolean;
var
  StandardOutput, ErrorOutput: AnsiString;
begin
  Result := False;
  // extract the archiver tool into the temporary folder
  ExtractTemporaryFile('7za.exe');
  // and execute it via the shell, to allow piping two of them for tgz archives
  if ExecWithResult(ExpandConstant('{tmp}\7za.exe'), Format('x "%s" %s', [FileName, Parameters]), '', SW_HIDE, ewWaitUntilTerminated, ResultCode, StandardOutput, ErrorOutput) then
  begin
    // the execution of the tool succeeded, but it doesn't mean that
    // extraction was successful; now we need to determine what exit
    // code the tool returned (for more information follow this link
    // http://sevenzip.sourceforge.jp/chm/cmdline/exit_codes.htm)
    case ResultCode of
      ERROR_7_ZIP_NO_ERROR, // all the files were successfully extracted
      ERROR_7_ZIP_WARNING: 
        Result := True; 
      (*ERROR_7_ZIP_FATAL_ERROR,  // errors occured
      ERROR_7_ZIP_CMD_LINE_ERROR: ;
      ERROR_7_ZIP_NOT_ENOUGH_MEMORY: ;
      ERROR_7_ZIP_USER_ABORT: ;*)
      else
        MsgBox(
          'An error occured while decompressing:'#13#10 +
          ''#13#10 +
          'Filename = ' + filename + #13#10 +
          'parameters = ' + parameters + #13#10 + 
          'Error level = ' + IntToStr(ResultCode) + #13#10 + 
          'StandardOutput = '#13#10 + 
          StandardOutput + #13#10 +
          'ErrorOutput = '#13#10 + 
          ErrorOutput + #13#10,
          mbError, 0);
    end;
  end
  else
  begin
    // the execution of the archiver tool failed; from SysErrorMessage(ResultCode)
    // you can get the reason of the failure
    MsgBox(
      'An error occured while decompressing:'#13#10 +
      ''#13#10 +
      'Filename = ' + filename + #13#10 +
      'parameters = ' + parameters + #13#10 + 
      SysErrorMessage(ResultCode),
      mbError, 0);
  end;
end;

function CustomExecute(const filename, parameters: string; var resultcode : Integer; var Handled: Boolean): Boolean;
var
  Extension: string;
begin
  Extension := ExtractFileExt(filename);

  if (Extension = '.zip') or (Extension = '.7z') then 
  begin
    Handled := True;
    Result := Decompress(filename, '"-o' + Parameters + '"', resultcode);
  end
  else if (Extension = '.tgz') or (Extension = '.tar.gz') then  
  begin
    Handled := True;
    Result := Decompress(filename, ExpandConstant('-so | "{tmp}\7za.exe" x -aoa -si -ttar "-o' + Parameters + '"'), resultcode);
  end;
end;

Note: the ExecWithResult method is similar to Dependency_ExecWithResult introduced by PR #79

obones avatar Mar 31 '22 10:03 obones