我可以在 Inno Setup 中将 .isl 文件用于带有预处理器指令的消息吗?

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

我定义了一个变量:

#define AppVersion "5.0"

Default.isl 文件中的许多标准消息在我的脚本的“[消息]”部分中被覆盖。这是一个例子:

[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.

我不喜欢所有这些消息都驻留在我的脚本中,我想将它们传输到相应的 .isl 文件中。问题是我无法在 .isl 文件中使用 {#AppVersion},因为它被解释为简单文本。考虑到 .isl 文件中包含 {#AppVersion}?

的消息,有没有办法覆盖这些消息?
  • 对于这种特殊情况,应用程序名称和版本,有一个简单的解决方案:

  • 如需注入少量其他信息,见下文。

  • 最终解决方案见

  • 请注意,这一切对于自定义消息来说都有些矫枉过正。对于那些,有更简单的解决方案:


如果您需要注入一些自定义信息,您可以像这样预处理 .isl 文件:

#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")}

以上示例将所有出现的 [token1][token2] 替换为 Token1Token2 预处理器变量的值。


理论上,可以在预处理器中完全实现这一点,而无需调用 PowerShell,使用 FileOpen, FileRead, StringChange, and SaveStringToFile 函数。

#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]

但是使用简单的函数式方法,您将达到预处理器的递归限制,因为语言文件的行数太多。它可以通过每次递归读取多行来解决,但这是一个 hack。

使用 #sub,它应该可以工作。但是一团糟。