1

I use three languages with my installer and at the moment I'm doing all the overrides inside my script. Here's an example:

[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» для продовження, або «Скасувати» для виходу. 

I have lots of messages overridden inside the script. I would like to know what is the most effective way to transfer all those overrides into the .isl files taking into account that I have preprocessor directives {#...} used. I could use FmtMessage(...), but that means that I would have to include FmtMessage(...) for every single message.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
JConstantine
  • 1,020
  • 7
  • 19

1 Answers1

1

First check, if some of the less invasive solutions might not cover your needs:
Can I use .isl files for the messages with preprocessor directives in Inno Setup?


If you want a full preprocessor support in .isl files, you can pass them through the actual Inno Setup preprocessor:

  • Factor out common include file (defines.iss) with all the variable definitions (and some support code):

    // Definitions
    #define AppVersion "1.2.3"
    // more definitions ...
    
    // Support code
    #define PreprocessedTranslationFile GetEnv("TEMP") + "\lang.isl"
    #define SavePreprocessedTranslation() SaveToFile(PreprocessedTranslationFile)
    
  • Include that file at the beginning of your .iss and all your .isl's:

    #include "defines.iss"
    
  • Call SavePreprocessedTranslation at the end of all your .isl's:

    #expr SavePreprocessedTranslation()
    
  • Make the preprocessor call iscc on the modified .isl files. It will of course fail, as the .isl is not a valid .iss, but the preprocessor part of iscc should complete and create the preprocessed .isl file.

    #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]
    
  • And use the preprocessed .isl files in the [Languages] section.

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

If you have problems, set DebugPreprocessLanguage to 1 to see the .isl preprocessor output.

You can even improve the process by making the preprocessor add the #include "defines.iss" and #expr SavePreprocessedTranslation() automatically to the .isl's before calling the iscc.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • If I specify the full path to the `.isl` files like this: `{#PreprocessLanguage("\Default.isl")}` the compiler spits out the error: _Error executing macro PreprocessLanguage \Default.isl failed to preprocess._ Can't I specify the full path like this? I need it because my language files are not in the same folder as the script file. – JConstantine Dec 07 '20 at 09:17
  • @JConstantine So what did you do to to debug the problem? Did you set the `DebugPreprocessLanguage` to 1 and did you check the `islpreprocess.log`? I guess the problem is that the `defines.iss` cannot be found. – Martin Prikryl Dec 07 '20 at 09:51
  • I did set the `DebugPreprocessLanguage` to 1 and what I have in the `islpreprocess.log` is just some jibberish: `ЌҐўҐа­® § ¤ ­® Ё¬п Ї ЇЄЁ.`. – JConstantine Dec 07 '20 at 09:55
  • @JConstantine You might be opening the file in a wrong encoding. – Martin Prikryl Dec 07 '20 at 10:16
  • I've just opened it with Notepad++. It says _Invalid folder name_ in Russian for some reason. The path I'm passing to the `#PreprocessLanguage` is `C:\ABOfficeProjects\Install\InnoSetupProject\Languages\English.isl`. The path is correct and the file does exist there. – JConstantine Dec 07 '20 at 10:22
  • What do you get if you replace `Local[0] = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"` with `Local[0] = "dir"`? – Martin Prikryl Dec 07 '20 at 10:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/225617/discussion-between-jconstantine-and-martin-prikryl). – JConstantine Dec 07 '20 at 10:47