I have defined a variable:
#define AppVersion "5.0"
There's a lot of standard messages from the Default.isl
file overridden in the `[Messages] section of my script. Here is an example:
[Messages]
en.WelcomeLabel1=Welcome to [name] {#AppVersion} Setup program. This program will install [name] {#AppVersion} on your computer.
en.SelectDirDesc=Where should [name] {#AppVersion} be installed?
en.SelectDirLabel3=Setup will install [name] {#AppVersion} into the following folder.
I don't like the fact that all those messages reside in my script and I would like to transfer them to the corresponding .isl
file. The problem is that I can't use {#AppVersion}
inside the .isl
file as it is interpreted as simple text. Is there a way to override those messages in the .isl
file taking into account that they contain {#AppVersion}
?
For this specific case, the application name and version, there's a simple solution:
How can I rewrite predefined messages for the WelcomePage in different languages in Inno Setup?
If you need to inject a small amount of other information, see below.
For ultimate solution, see Full preprocessor support in Inno Setup language files (isl)
Note that this all would be an overkill for custom messages. For those, there are easier solutions: How can I use language files with custom messages with preprocessor constants?
If you need to inject some custom piece of information, you can preprocess .isl files like this:
#define Token1 "value1"
#define Token2 "value2"
#define PreprocessLanguage(Path) \
Local[0] = GetEnv("TEMP") + "\" + ExtractFileName(Path), \
Local[1] = \
"-ExecutionPolicy Bypass -Command """ + \
"$contents = Get-Content '" + CompilerPath + "\" + Path + "'; " + \
"$contents = $contents -replace '[token1]', '" + Token1 +"'; " + \
"$contents = $contents -replace '[token2]', '" + Token2 +"'; " + \
"Set-Content -Path '" + Local[0] + "' -Value $contents;" + \
"""", \
Exec("powershell.exe", Local[1], , , SW_HIDE), \
Local[0]
[Languages]
Name: "en"; MessagesFile: {#PreprocessLanguage("Default.isl")}
Name: "nl"; MessagesFile: {#PreprocessLanguage("Languages\Dutch.isl")}
The above example replaces all occurrences of [token1]
and [token2]
with values of Token1
and Token2
preprocessor variables.
Theoretically, it is possible to implement this fully in the preprocessor without invoking PowerShell, with use of FileOpen
, FileRead
, StringChange
, and SaveStringToFile
functions.
#define Token1 "value1"
#define Token2 "value2"
#define PreprocessLanguageLines(Handle, OutPath) \
!FileEof(Handle) ? \
Local[0] = FileRead(Handle), \
Local[0] = StringChange(Local[0], "[token1]", Token1), \
Local[0] = StringChange(Local[0], "[token1]", Token2), \
SaveStringToFile(OutPath, Local[0] + NewLine, 1, 0), \
PreprocessLanguageLines(Handle, OutPath) \
: ""
#define PreprocessLanguage(Path) \
Local[0] = GetEnv("TEMP") + "\" + ExtractFileName(Path), \
SaveStringToFile(Local[0], "", 0, 0), \
Local[1] = FileOpen(CompilerPath + "\" + Path), \
PreprocessLanguageLines(Local[1], Local[0]), \
FileClose(Local[1]), \
Local[0]
But with the straightforward functional approach, you will hit recursion limit of the preprocessor as the language files have too many lines. It can get solved by reading multiple lines per recursion, but that's a hack.
With use of the #sub
, it should work. But it's a mess.