Inno Setup语言文件(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(...)

首先检查一些侵入性较小的解决方案是否无法满足您的需求:
我可以在Inno Setup中使用带有预处理器指令的.isl文件来处理消息吗?


如果你想在.il文件中提供完整的预处理器支持,你可以通过实际的Inno Setup预处理器:

  • Factor-out公共包含文件(defines.iss(,包含所有变量定义(和一些支持代码(:

    // Definitions
    #define AppVersion "1.2.3"
    // more definitions ...
    // Support code
    #define PreprocessedTranslationFile GetEnv("TEMP") + "lang.isl"
    #define SavePreprocessedTranslation() SaveToFile(PreprocessedTranslationFile)
    
  • 将该文件包含在你的.iss和你所有的.ist:的开头

    #include "defines.iss"
    
  • 在所有.ist:结束时致电SavePreprocessedTranslation

    #expr SavePreprocessedTranslation()
    
  • 使预处理器对修改后的.isl文件调用iscc。它当然会失败,因为.iss不是有效的.iss,但iscc的预处理器部分应该完成并创建预处理的.iss文件。

    #define DebugPreprocessLanguage 0
    #define PreprocessLanguage(Path) 
    Local[0] = "C:Program Files (x86)Inno Setup 6ISCC.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]部分中经过预处理的.sl文件。

    [Languages]
    Name: "en"; MessagesFile: {#PreprocessLanguage("Default.isl")}
    Name: "nl"; MessagesFile: {#PreprocessLanguage("Dutch.isl")}
    

如果有问题,请将DebugPreprocessLanguage设置为1,以查看.sl预处理器的输出。

您甚至可以通过使预处理器在调用iscc之前将#include "defines.iss"#expr SavePreprocessedTranslation()自动添加到.sil中来改进该过程。

最新更新