7

I want to call a function after installing a folder, but the InstallEnv function is seems to be called several times, maybe for each file is the folder (to be confirmed). Is there a way to call it only once after it installed all of those files? I can't use the Run section because I want to do error catching with the return code.

Source: "InputFiles\virtualenv-1.8.2\*"; DestDir: "{tmp}/virtualenv"; \
    Flags: recursesubdirs; AfterInstall: InstallEnv; 
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Amaranth
  • 2,433
  • 6
  • 36
  • 58
  • 1
    Looking at both your questions, don't you rather want to execute what you need in [`CurStepChanged`](http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents&anchor=CurStepChanged) event method when the `CurStep` parameter will be `ssPostInstall` ? – TLama Nov 27 '13 at 17:12
  • I actually did try that on Monday, but when a execution returns a code different than Zero, I want to make the installation fail (or abort it). However, the code `WizardForm.Close;` does not work at `ssPostInstall` (maybe because it's after the actual installation). – Amaranth Nov 27 '13 at 18:16
  • 1
    I see. You are looking for a way how to abort installation process (and rollback changes) if something inside the `InstallEnv` procedure goes wrong. Well, I wouldn't rely on the name of the last installed file since it makes me feel somehow unpredictable. Another option might be write a `BeforeInstall` procedure for the next installed `[Files]` entry. Or maybe make a pass counter for that `InstallEnv` procedure and the total count of files determine by preprocessor. You'd increment that counter whenever the procedure will be called and if it reaches that constant value, it was the last file. – TLama Nov 27 '13 at 18:47
  • Anyway, do you really need to call that procedure after all the files are installed. Couldn't you modify it so that it would process just the currently installed file ? I just can't imagine what do you need to do over all those installed files that wouldn't be possible to do over each file incrementally. – TLama Nov 27 '13 at 18:54
  • I ended up using the `CurStep` With a check not to execute the others commands if the ReturnCode is greater than 0. I also diplay a message box and log the output in a file if there's an error. – Amaranth Nov 28 '13 at 02:13

2 Answers2

5

There is no way to call it at the end of the installation of that group of files, from within a single entry. However it is possible to call the function at the appropriate time by making use of a dummy entry:

[Files]
Source: "InputFiles\virtualenv-1.8.2\*"; DestDir: "{tmp}\virtualenv"; Flags: recursesubdirs
Source: dummy.txt; DestDir: {tmp}; AfterInstall: InstallEnv

The Source file must exist but it can be a zero-byte file. As installation is into {tmp} it will be deleted after install anyway so its contents are irrelevant.

This works because [Files] entries are installed in the order specified.

Miral
  • 12,637
  • 4
  • 53
  • 93
3

Yes, it executes once per each file. The reference says about it (emphasized by me):

A BeforeInstall or AfterInstall function for a [Files] section entry using a wildcard is called once per file matching the wildcard. Use CurrentFileName to check for which file the function is called.

And no, there is no way to call it once after all the files are installed. If you were going to run it only once, it wouldn't be a problem, since you might declare a flag variable, indicating that the function was already called, but you want to detect if it's the last call, and for this there is no workaround.

Well, maybe if you would know, which file will be the latest installed from that folder, you might check that against the result of the CurrentFileName function call, but I doubt that you can determine which one will be installed as last at compilation time (since at runtime, there is currently no way to get list of files to be installed).

TLama
  • 75,147
  • 17
  • 214
  • 392