Czy mogę używać plików .isl do wiadomości z dyrektywami preprocesora w Inno Setup?
Zdefiniowałem zmienną:
#define AppVersion "5.0"
Jest wiele standardowych wiadomości z Default.isl
pliku 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 .isl
pliku. Problem polega na tym, że nie mogę użyć pliku {#AppVersion}
wewnątrz .isl
pliku, ponieważ jest on interpretowany jako prosty tekst. Czy istnieje sposób na zastąpienie tych wiadomości w .isl
pliku, biorąc pod uwagę, że zawierają {#AppVersion}
?
Odpowiedzi
W tym konkretnym przypadku, jeśli chodzi o nazwę i wersję aplikacji, istnieje proste rozwiązanie:
Jak mogę przepisać wstępnie zdefiniowane wiadomości na WelcomePage w różnych językach w Inno Setup?Jeśli potrzebujesz wstrzyknąć niewielką ilość innych informacji, patrz poniżej.
Aby uzyskać najlepsze rozwiązanie, zobacz Pełna obsługa preprocesorów w plikach językowych Inno Setup (isl)
Zauważ, że to wszystko byłoby przesadą w przypadku niestandardowych wiadomości. Dla nich są prostsze rozwiązania: Jak mogę używać plików językowych z niestandardowymi komunikatami ze stałymi preprocesora?
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 Token1
i Token2
.
Teoretycznie jest to możliwe do wykonania tego w pełni preprocesora bez wywoływania PowerShell, przy użyciu FileOpen
, FileRead
, StringChange
oraz SaveStringToFile
funkcji.
#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 #sub
powinno działać. Ale to bałagan.