Czy mogę używać plików .isl do wiadomości z dyrektywami preprocesora w Inno Setup?

Nov 20 2020

Zdefiniowałem zmienną:

#define AppVersion "5.0"

Jest wiele standardowych wiadomości z Default.islpliku nadpisanych w sekcji `[Wiadomości] mojego skryptu. Oto przykład:

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

Nie podoba mi się fakt, że wszystkie te wiadomości znajdują się w moim skrypcie i chciałbym przenieść je do odpowiedniego .islpliku. Problem polega na tym, że nie mogę użyć pliku {#AppVersion}wewnątrz .islpliku, ponieważ jest on interpretowany jako prosty tekst. Czy istnieje sposób na zastąpienie tych wiadomości w .islpliku, biorąc pod uwagę, że zawierają {#AppVersion}?

Odpowiedzi

1 MartinPrikryl Nov 20 2020 at 15:49

Jeśli chcesz wprowadzić niestandardową informację, możesz wstępnie przetworzyć pliki .isl w następujący sposób:

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

Powyższy przykład zastępuje wszystkie wystąpienia [token1]i [token2]wartościami zmiennych preprocesora Token1i Token2.


Teoretycznie jest to możliwe do wykonania tego w pełni preprocesora bez wywoływania PowerShell, przy użyciu FileOpen, FileRead, StringChangeoraz SaveStringToFilefunkcji.

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

Ale dzięki prostemu podejściu funkcjonalnemu osiągniesz limit rekursji preprocesora, ponieważ pliki językowe mają zbyt wiele linii. Można go rozwiązać, czytając wiele wierszy na rekursję, ale to hack.

Przy użyciu #subpowinno działać. Ale to bałagan.