Inno Setup 语言文件 (isl) 中的完整预处理器支持
Full preprocessor support in Inno Setup language files (isl)
我的安装程序使用三种语言,目前我正在我的脚本中进行所有覆盖。这是一个例子:
[Messages]
en.SetupWindowTitle=Setup - %1 {#AppVersion}
ru.SetupWindowTitle=Установка - %1 {#AppVersion}
ua.SetupWindowTitle=Встановлення - %1 {#AppVersion}
en.SetupAppRunningError=Setup has detected that {#SetupSetting('VersionInfoOriginalFileName')} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
ru.SetupAppRunningError=Обнаружен запущенный экземпляр {#SetupSetting('VersionInfoOriginalFileName')}.%n%nПожалуйста, закройте все экземпляры приложения, затем нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.
ua.SetupAppRunningError=Виявлено запущений екземпляр {#SetupSetting('VersionInfoOriginalFileName')}.%n%nБудь ласка, закрийте всі копії програми та натисніть «OK» для продовження, або «Скасувати» для виходу.
[CustomMessages]
en.AppRunningError=Setup has detected that {#AppExeName} is currently running.%n%nPlease, close the {#AppExeName} application, then click «OK» to continue or «Cancel» to exit.
ru.AppRunningError=В памяти находится {#AppExeName}.%n%nЗавершите работу {#AppExeName} и нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.
ua.AppRunningError=В пам'яті знаходиться {#AppExeName}.%n%nЗавершіть роботу {#AppExeName} та натисніть «OK» для продовження, або «Скасувати» для виходу.
我在脚本中覆盖了很多消息。考虑到我使用了预处理器指令 {#...}
,我想知道将所有这些覆盖转移到 .isl
文件中的最有效方法是什么。我可以使用 FmtMessage(...)
,但这意味着我必须为每条消息包含 FmtMessage(...)
。
首先检查一下,如果一些侵入性较小的解决方案可能无法满足您的需求:
如果你想在 .isl 文件中获得完整的预处理器支持,你可以通过实际的 Inno Setup 预处理器传递它们:
分解出包含所有变量定义(和一些支持代码)的通用包含文件 (defines.iss
):
// Definitions
#define AppVersion "1.2.3"
// more definitions ...
// Support code
#define PreprocessedTranslationFile GetEnv("TEMP") + "\lang.isl"
#define SavePreprocessedTranslation() SaveToFile(PreprocessedTranslationFile)
在您的 .iss 和所有 .isl 的开头包含该文件:
#include "defines.iss"
在所有 .isl 的末尾调用 SavePreprocessedTranslation
:
#expr SavePreprocessedTranslation()
对修改后的 .isl 文件进行预处理器调用 iscc
。它当然会失败,因为 .isl 不是有效的 .iss,但是 iscc
的预处理器部分应该完成并创建预处理的 .isl 文件。
#define DebugPreprocessLanguage 0
#define PreprocessLanguage(Path) \
Local[0] = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe", \
DeleteFileNow(PreprocessedTranslationFile), \
Local[1] = DebugPreprocessLanguage ? SourcePath + "\islpreprocess.log" : "nul", \
Local[2] = "/C """"" + Local[0] + """ """ + Path + """ " + \
">> " + Local[1] + " 2>&1 """, \
Exec("cmd", Local[2], SourcePath, , SW_HIDE), \
(FileExists(PreprocessedTranslationFile) || \
Error(Path + " failed to preprocess")), \
Local[3] = GetEnv("TEMP") + "\" + ExtractFileName(Path), \
CopyFile(PreprocessedTranslationFile, Local[3]), \
DeleteFileNow(PreprocessedTranslationFile), \
Local[3]
并在 [Languages]
部分使用预处理后的 .isl 文件。
[Languages]
Name: "en"; MessagesFile: {#PreprocessLanguage("Default.isl")}
Name: "nl"; MessagesFile: {#PreprocessLanguage("Dutch.isl")}
如果遇到问题,请将 DebugPreprocessLanguage
设置为 1
以查看 .isl 预处理器输出。
您甚至可以通过让预处理器在调用 iscc
.
之前自动将 #include "defines.iss"
和 #expr SavePreprocessedTranslation()
添加到 .isl 来改进流程
我的安装程序使用三种语言,目前我正在我的脚本中进行所有覆盖。这是一个例子:
[Messages]
en.SetupWindowTitle=Setup - %1 {#AppVersion}
ru.SetupWindowTitle=Установка - %1 {#AppVersion}
ua.SetupWindowTitle=Встановлення - %1 {#AppVersion}
en.SetupAppRunningError=Setup has detected that {#SetupSetting('VersionInfoOriginalFileName')} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
ru.SetupAppRunningError=Обнаружен запущенный экземпляр {#SetupSetting('VersionInfoOriginalFileName')}.%n%nПожалуйста, закройте все экземпляры приложения, затем нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.
ua.SetupAppRunningError=Виявлено запущений екземпляр {#SetupSetting('VersionInfoOriginalFileName')}.%n%nБудь ласка, закрийте всі копії програми та натисніть «OK» для продовження, або «Скасувати» для виходу.
[CustomMessages]
en.AppRunningError=Setup has detected that {#AppExeName} is currently running.%n%nPlease, close the {#AppExeName} application, then click «OK» to continue or «Cancel» to exit.
ru.AppRunningError=В памяти находится {#AppExeName}.%n%nЗавершите работу {#AppExeName} и нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.
ua.AppRunningError=В пам'яті знаходиться {#AppExeName}.%n%nЗавершіть роботу {#AppExeName} та натисніть «OK» для продовження, або «Скасувати» для виходу.
我在脚本中覆盖了很多消息。考虑到我使用了预处理器指令 {#...}
,我想知道将所有这些覆盖转移到 .isl
文件中的最有效方法是什么。我可以使用 FmtMessage(...)
,但这意味着我必须为每条消息包含 FmtMessage(...)
。
首先检查一下,如果一些侵入性较小的解决方案可能无法满足您的需求:
如果你想在 .isl 文件中获得完整的预处理器支持,你可以通过实际的 Inno Setup 预处理器传递它们:
分解出包含所有变量定义(和一些支持代码)的通用包含文件 (
defines.iss
):// Definitions #define AppVersion "1.2.3" // more definitions ... // Support code #define PreprocessedTranslationFile GetEnv("TEMP") + "\lang.isl" #define SavePreprocessedTranslation() SaveToFile(PreprocessedTranslationFile)
在您的 .iss 和所有 .isl 的开头包含该文件:
#include "defines.iss"
在所有 .isl 的末尾调用
SavePreprocessedTranslation
:#expr SavePreprocessedTranslation()
对修改后的 .isl 文件进行预处理器调用
iscc
。它当然会失败,因为 .isl 不是有效的 .iss,但是iscc
的预处理器部分应该完成并创建预处理的 .isl 文件。#define DebugPreprocessLanguage 0 #define PreprocessLanguage(Path) \ Local[0] = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe", \ DeleteFileNow(PreprocessedTranslationFile), \ Local[1] = DebugPreprocessLanguage ? SourcePath + "\islpreprocess.log" : "nul", \ Local[2] = "/C """"" + Local[0] + """ """ + Path + """ " + \ ">> " + Local[1] + " 2>&1 """, \ Exec("cmd", Local[2], SourcePath, , SW_HIDE), \ (FileExists(PreprocessedTranslationFile) || \ Error(Path + " failed to preprocess")), \ Local[3] = GetEnv("TEMP") + "\" + ExtractFileName(Path), \ CopyFile(PreprocessedTranslationFile, Local[3]), \ DeleteFileNow(PreprocessedTranslationFile), \ Local[3]
并在
[Languages]
部分使用预处理后的 .isl 文件。[Languages] Name: "en"; MessagesFile: {#PreprocessLanguage("Default.isl")} Name: "nl"; MessagesFile: {#PreprocessLanguage("Dutch.isl")}
如果遇到问题,请将 DebugPreprocessLanguage
设置为 1
以查看 .isl 预处理器输出。
您甚至可以通过让预处理器在调用 iscc
.
#include "defines.iss"
和 #expr SavePreprocessedTranslation()
添加到 .isl 来改进流程