InnoDependencyInstaller
InnoDependencyInstaller copied to clipboard
Introduce a way to specify a custom Execute method to be called when installing a dependency
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