How to use Pascal Inno Setup ExpandConstant with a string variable?

zePit picture zePit · Aug 17, 2012 · Viewed 10.1k times · Source

For an installation program, I need to create folder links.

For this, I create the target folders using the '[Dirs]' sections. No problem.

Then, in '[Code]' section, using function 'CurStepChanged(ssPostInstall)', I read a temporary installed file to obtain a list of folder links to create. Each line of the file contains a target folder path name, and a link path name... Using Inno Setup constants. Each value is read and stored in as 'String' variable.

When I pass these string variables to 'ExpandConstant(lLinkTarg)', I get an internal runtime error on any of the constant names.

If I copy paste the string content to a 'ExpandConstant('{#gRepNasSvg}\UT{code:getProjetc}\Docs')' call, then it works...

Any hint about what I do wrong ?

Thanks in advance. L.

procedure CurStepChanged(CurStep: TSetupStep);
var
    lFileName: String;
    lLinkList: TArrayOfString;
    lIndex: Integer;
    lLinkLine: String;
    lLinkName: String;
    lLinkTarg: String;
    lSepPos: Integer;

begin
    // Après l'étape d'installation...
    if CurStep = ssPostInstall then
        begin
            // Si le fichier listant les liens à créer existe...
            lFileName := ExpandConstant('{tmp}') + '\' + ExpandConstant('{#gFicListeLiens}');
            if FileExists(lFileName) then
                begin
                    // Lecture du contenu du fichier.
                    LoadStringsFromFile(lFileName, lLinkList);

                    // Pour chaque ligne lue...
                    for lIndex := 0 to GetArrayLength(lLinkList) - 1 do
                    begin
                        // Lecture de la ligne.
                        lLinkLine := Trim(lLinkList[lIndex]);

                        // Si ce n'est pas un commentaire...
                        if (Length(lLinkLine) > 0) and (lLinkLine[1] <> ';') then
                            begin
                                // Recherche du séparateur.
                                lSepPos := Pos('>', lLinkLine);
                                if lSepPos > 0 then
                                    begin
                                        // Get target location.
                                        lLinkTarg := Trim(Copy(lLinkLine, 1, lSepPos - 1));
MsgBox(lLinkTarg, mbInformation, MB_OK);

                                        // NEXT LINE FAILS !
                                        lLinkTarg := ExpandConstant(lLinkTarg) ;
MsgBox(lLinkTarg, mbInformation, MB_OK);

                                        // Get link location.
                                        lLinkName := Trim(Copy(lLinkLine, lSepPos + 1, Length(lLinkLine) - lSepPos));
MsgBox(lLinkName, mbInformation, MB_OK);

                                    end
                            end
                    end
                end
        end
end;

Some stuff I have forgotten.

Link description variable is of the form '{#gRepNasSvg}\UT{code:getProjetc}\Docs'...

Answer

Miral picture Miral · Aug 18, 2012

ExpandConstant('{tmp}\{#gFicListeLiens}');

(You should always include at least the \ following a directory constant in the call to ExpandConstant, and there's no harm in including additional text in there provided it doesn't contain any of the special characters.)

What is the content of the file you're trying to read in, though?

Note that ExpandConstant does not (and cannot) expand {#var} style constants, these are expanded at compile time by the preprocessor, and can't be expanded at runtime. It's also usually bad style to try to expand {code:...} constants from within [Code] functions.

What's the reason for using a file in the first place? Is it generated by something during installation? If not (or even if so, and you can do the generation in the script instead of something external), you should just use an array within the code.