Archive: INSTDIR vs Component


INSTDIR vs Component
  Hi All -

Does anyone know how to have the choice of the installation directory for each component I got in the code?

Is there an easy way to proceed using the standard Page or do I have to create a custom one?


Adding some precision:

How can I have in a Directory Page several lines corresponding of the install path of the different components selected in the Component Page?


There's at least two simple ways you could do this... both require you to put multiple Directory pages behind the Components page.

The following is assuming you're using the Modern UI. It's a bit untested, but should be fine.


# variables to hold the installation directories

>var Component1Dir
>var Component2Dir
>var Component3Dir

># components page
>!insertmacro MUI_PAGE_COMPONENTS

># multiple directory pages
>!define MUI_PAGE_CUSTOMFUNCTION_PRE Component1DirPre
>!define MUI_DIRECTORYPAGE_VARIABLE Component1Dir
>!insertmacro MUI_PAGE_DIRECTORY

>!define MUI_PAGE_CUSTOMFUNCTION_PRE Component2DirPre
>!define MUI_DIRECTORYPAGE_VARIABLE Component2Dir
>!insertmacro MUI_PAGE_DIRECTORY

>!define MUI_PAGE_CUSTOMFUNCTION_PRE Component3DirPre
>!define MUI_DIRECTORYPAGE_VARIABLE Component3Dir
>!insertmacro MUI_PAGE_DIRECTORY

># The file installation 'page'
>!insertmacro MUI_PAGE_INSTFILES

># The components (sections)
>Section Component1
# stuff here. Be sure to use the directory variable corresponding
# to the directory page used. In this case, for example:
SetOutPath "$Component1Dir"
File "somefile"
File "someotherfile"
>SectionEnd

Section Component2
# stuff here
SetOutPath "$Component2Dir"
File "somefile"
File "someotherfile"
>SectionEnd

Section Component3
# stuff here
SetOutPath "$Component3Dir"
File "somefile"
File "someotherfile"
>SectionEnd

># Functions run before showing each directory page.
# Here we'll call Abort to stop the page from showing up
# if the user didn't select the component
>Function Component1DirPre
# Get the flags for the section
SectionGetFlags ${Component1} $R0
# Binary 'and' with value '1' (selected or not)
IntOp $R0 $R0 & 1
# If it is not selected
IntCmp $R0 0 0 +2
# Then Abort. This will prevent the page from showing up
Abort
# Otherwise, continue
>FunctionEnd

>Function Component2DirPre
SectionGetFlags${Component2} $R0
IntOp $R0 $R0& 1
IntCmp $R0 0 0+2
Abort
FunctionEnd

>Function Component3DirPre
SectionGetFlags${Component3} $R0
IntOp $R0 $R0& 1
IntCmp $R0 0 0+2
Abort
FunctionEnd
>
--------------------------------------------------

Another method, where you wouldn't require multiple directory variables, would be to put the actual file installation/operation instructions in the Directory pages' Post functions. This is less desirable for various reasons - mostly the log display won't be right. If you don't care about that, though, it might be easier to work with as all the code corresponding to a particular directory is right there in the directory handling functions.

--------------------------------------------------

Lastly, you could make a custom page with multiple directory fields. This would look cleaner (having a user go through 5 directory pages, for example, would be a bit ick), but also require much more work (think hiding fields if the components aren't selected, still have to store multiple directory variables, etc.)

To specifically answer your second post : yes, you'd have to create a custom page.
I've done one with two directories myself, and it's not impossible, but it's not supersimple either :)
The most limiting factor is dialog real-estate. You'd need a bigger dialog if you want a whole bunch of directory fields. That, or put up with a relatively ugly page.