Can I use .isl files for the messages with preprocessor directives in Inno Setup?

北城余情 提交于 2020-11-24 17:22:17

问题


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}?


回答1:


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 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 the #sub, it should work. But it's a mess.


It might be possible to improve that, to do a full preprocessing using the actual Inno Setup preprocessor:

  • Factor out common include file with all the variable definitions (and possibly including the [Setup] section, if SetupSetting is used)
  • #include that file at the beginning of your .iss.
  • Do the same for all your .isl's and call SaveToFile at the end. Though you can even make the preprocessor to do that automatically by creating a temporary copies of the .isl files with necessary modifications.
  • Make the preprocessor call iscc on the modified .isl files. It will of course fail, as the .isl is not a valid .iss, but the preprocessor should complete and create the preprocessed file.
  • Use the preprocessed file as the language file in .iss.

I didn't try to implement this. But I believe it should work.


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?



来源:https://stackoverflow.com/questions/64932221/can-i-use-isl-files-for-the-messages-with-preprocessor-directives-in-inno-setup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!