Kann ich .isl-Dateien für Nachrichten mit Präprozessoranweisungen in Inno Setup verwenden?

Nov 20 2020

Ich habe eine Variable definiert:

#define AppVersion "5.0"

Es gibt viele Standardnachrichten aus der Default.islDatei, die im Abschnitt "[Nachrichten]" meines Skripts überschrieben wurden. Hier ist ein Beispiel:

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

Die Tatsache, dass sich all diese Nachrichten in meinem Skript befinden, gefällt mir nicht und ich möchte sie in die entsprechende .islDatei übertragen. Das Problem ist, dass ich {#AppVersion}die .islDatei nicht verwenden kann, da sie als einfacher Text interpretiert wird. Gibt es eine Möglichkeit, diese Nachrichten in der .islDatei zu überschreiben, indem berücksichtigt wird, dass sie enthalten sind {#AppVersion}?

Antworten

1 MartinPrikryl Nov 20 2020 at 15:49
  • Für diesen speziellen Fall, den Anwendungsnamen und die Version, gibt es eine einfache Lösung:
    Wie kann ich vordefinierte Nachrichten für die WelcomePage in Inno Setup in verschiedenen Sprachen umschreiben?

  • Wenn Sie eine kleine Menge anderer Informationen injizieren müssen, siehe unten.

  • Eine endgültige Lösung finden Sie unter Vollständige Präprozessorunterstützung in Inno Setup-Sprachdateien (isl).

  • Beachten Sie, dass dies alles ein Overkill für benutzerdefinierte Nachrichten wäre. Für diese gibt es einfachere Lösungen: Wie kann ich Sprachdateien mit benutzerdefinierten Nachrichten mit Präprozessor-Konstanten verwenden?


Wenn Sie benutzerdefinierte Informationen einfügen müssen, können Sie .isl-Dateien wie folgt vorverarbeiten:

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

Das obige Beispiel ersetzt alle Vorkommen von [token1]und [token2]durch Werte von Token1und Token2Präprozessorvariablen.


Theoretisch ist es möglich , diese vollständig ohne Aufruf Powershell im Preprocessor zu implementieren, mit der Verwendung von FileOpen, FileRead, StringChangeund SaveStringToFileFunktionen.

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

Mit dem einfachen Funktionsansatz erreichen Sie jedoch die Rekursionsgrenze des Präprozessors, da die Sprachdateien zu viele Zeilen enthalten. Es kann gelöst werden, indem mehrere Zeilen pro Rekursion gelesen werden, aber das ist ein Hack.

Mit dem #subsollte es funktionieren. Aber es ist ein Durcheinander.