23

Inno Setup has command line parameter /LOG="filename". Can I specify a log filename from inside the Inno Setup script, so I can include it later in my error reports?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
sashoalm
  • 75,001
  • 122
  • 434
  • 781

3 Answers3

24

You can set the SetupLogging option (SetupLogging=yes) then integrate the following code into your script to copy the log somewhere.

procedure CurStepChanged(CurStep: TSetupStep);
var
  logfilepathname, logfilename, newfilepathname: string;
begin
  logfilepathname := ExpandConstant('{log}');
  logfilename := ExtractFileName(logfilepathname);
  newfilepathname := ExpandConstant('{app}\') + logfilename;

  if CurStep = ssDone then
  begin
    FileCopy(logfilepathname, newfilepathname, false);
  end;
end; 
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
mirtheil
  • 8,952
  • 1
  • 30
  • 29
  • 8
    Do you really think it's necessary to recalculate the paths and file names again and again for every setup step? Why not move that into the `if CurStep = ssDone then`-block? – Oliver Giesen Mar 04 '11 at 12:49
  • 8
    +1 Mittheil! I've used your tip but call in DeinitializeSetup instead. Then the log is copied even if the user exits Setup before anything is installed. – Lars Nov 25 '13 at 23:46
  • @MartinPrikryl Is it possible to add my own lines to the installation log? – JConstantine Apr 30 '20 at 08:59
  • 1
    @JConstantine See [How to log [file copying process\] in Inno Setup](https://stackoverflow.com/q/34634167/850848) – Martin Prikryl Apr 30 '20 at 09:11
16

Following the comment from Lars I used the DeinitializeSetup() procedure, but I also changed the new file path to use the {src} constant to copy the log file to the directory that the installer is run from instead of {app} constant which may/may not be created if the user cancels the installation:

// Called just before Setup terminates. Note that this function is called even if the user exits Setup before anything is installed.
procedure DeinitializeSetup();
var
  logfilepathname, logfilename, newfilepathname: string;
begin
  logfilepathname := ExpandConstant('{log}');
  logfilename := ExtractFileName(logfilepathname);
  // Set the new target path as the directory where the installer is being run from
  newfilepathname := ExpandConstant('{src}\') + logfilename;

  FileCopy(logfilepathname, newfilepathname, false);
end; 
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
JasonMcF
  • 632
  • 8
  • 18
1

Extending the example from JasonMcF... checking if the uninstaller was created to see if the setup was finished successfully.

// Called just before Setup terminates.
// Note that this function is called even if the user exits Setup before anything is installed.
procedure DeinitializeSetup();
var
    unInstaller, logFilePath, logFileName, newFilePath: string;
begin
    unInstaller := ExpandConstant('{uninstallexe}');

    logFilePath := ExpandConstant('{log}');
    logFileName := ExtractFileName(logFilePath);
  
    if FileExists(unInstaller) then
    begin
        // uninstaller exists, setup was finished successfully, copy log to app directory
        newFilePath := ExpandConstant('{app}\') + logFileName;
    end
        else
    begin
        // setup didn't finish successfully, copy log to src directory
        newFilePath := ExpandConstant('{src}\') + logFileName;
    end;

    Log('DeinitializeSetup');
    Log('- unInstaller:' + unInstaller);
    Log('- logFilePath:' + logFilePath);
    Log('- newFilePath:' + newFilePath);

    FileCopy(logFilePath, newFilePath, false);
end;
WoWeh
  • 58
  • 5
  • 1
    For checking if installation succeeded or not, see [How to call an exe when Inno Setup installation fails (within the installer itself)?](https://stackoverflow.com/q/33343283/850848) – Martin Prikryl Apr 22 '21 at 11:00