NSIS works with LangString incorrectly - localization

I have an installer, it builds automatically (on TFS) by using NSIS command line features
"..\..\NSIS\makensis.exe" /DBUILD_NUMBER=28311 /DPRODUCT_LANGUAGE=English "MTService_setup.nsi"
The installer must use language, which specified in PRODUCT_LANGUAGE parameter. I've done it in the following way
!insertmacro MUI_LANGUAGE "${PRODUCT_LANGUAGE}"
When I build installer in such way, the common language of the interface is correct. But it uses default system language for LangString. So, if default system language is not English, it shows LangString on another language in the English installer.
I've tried to change script to avoid command line parameters (for test purposes)
!insertmacro MUI_LANGUAGE "English"
It doesn't work too.
I've tried to change script to
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "Russian"
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
It works, but, of course, it shows language selection dialog. I want to use specific ${PRODUCT_LANGUAGE} without any dialog.
So, how can I fix it?

You did not show us your LangString code in your example so it is hard to say what the problem is!
Here is a working example based on code in the MUI readme:
Outfile "test.exe"
Requestexecutionlevel user
!include MUI2.nsh
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE Swedish ;First language is the default if a better match is not found
!insertmacro MUI_LANGUAGE Danish
Function .onInit
StrCpy $language ${LANG_DANISH} ;Always force Danish?
FunctionEnd
Section "Section Name 1" Section1
SectionEnd
Section "Section Name 2" Section2
SectionEnd
LangString DESC_Section1 ${LANG_SWEDISH} "Bork, bork, bork!"
LangString DESC_Section2 ${LANG_SWEDISH} "Aweenda shmure da froog's legs."
LangString DESC_Section1 ${LANG_DANISH} "Danish text here for section 1"
LangString DESC_Section2 ${LANG_DANISH} "...and section 2"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1)
!insertmacro MUI_DESCRIPTION_TEXT ${Section2} $(DESC_Section2)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

Related

GetLocaleInfo in NSIS

I'm trying to get locale infos in NSIS (using this code).
As my system is in french, I'd hope to get a string like "fr-FR", but I'm getting chineese synbols instead :/
Any idea of what I'm doing wrong?
!define LOCALE_ILANGUAGE '0x1' ;System Language Resource ID
!define LOCALE_SLANGUAGE '0x2' ;System Language & Country [Cool]
!define LOCALE_SABBREVLANGNAME '0x3' ;System abbreviated language
!define LOCALE_SNATIVELANGNAME '0x4' ;System native language name [Cool]
!define LOCALE_ICOUNTRY '0x5' ;System country code
!define LOCALE_SCOUNTRY '0x6' ;System Country
!define LOCALE_SABBREVCTRYNAME '0x7' ;System abbreviated country name
!define LOCALE_SNATIVECTRYNAME '0x8' ;System native country name [Cool]
!define LOCALE_IDEFAULTLANGUAGE '0x9' ;System default language ID
!define LOCALE_IDEFAULTCOUNTRY '0xA' ;System default country code
!define LOCALE_IDEFAULTCODEPAGE '0xB' ;System default oem code page
Function getLocale
System::Call 'kernel32::GetSystemDefaultLangID() i .r0'
System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SNATIVELANGNAME}, t .r1, i ${NSIS_MAX_STRLEN}) i r0'
System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SNATIVECTRYNAME}, t .r2, i ${NSIS_MAX_STRLEN}) i r0'
System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SLANGUAGE}, t .r3, i ${NSIS_MAX_STRLEN}) i r0'
MessageBox MB_OK|MB_ICONINFORMATION "Your System LANG Code is: $0. $\r$\nYour system language is: $1. $\r$\nYour system language is: $2. $\r$\nSystem Locale INFO: $3."
FunctionEnd
Same kind of error with these constants:
!define LOCALE_SISO639LANGNAME 0x00000059 ; ISO abbreviated language name, eg "en"
!define LOCALE_SISO3166CTRYNAME 0x0000005A ; ISO abbreviated country/region name, eg "US"
Change GetLocaleInfoA to GetLocaleInfo. NSIS v3 will autodetect the A/W function when the t type parameter is used.
Ansi strings when interpreted as Unicode tends to look like Chinese.

VERSIONINFO resource not being shown in EXE properties

I'm using Delphi 10.0 Seattle on a machine with Windows 10.
We have a system that has several executables. We use the version information via .rc file:
1 VERSIONINFO
FILEVERSION 18,2,0,1660
PRODUCTVERSION 18,2,0,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS (VS_FF_SPECIALBUILD|VS_FF_PRERELEASE)
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041604E4"
BEGIN
VALUE "CompanyName", "BLA BLA BLA\0"
VALUE "FileDescription", "BLA BLABLA - DESCRICAO\0"
VALUE "FileVersion", "18.2.0.1660\0"
VALUE "InternalName", "nomexecutavel.exe\0"
VALUE "LegalCopyright", "Copyright 2018\0"
VALUE "LegalTrademarks", "BLA BLA BLA é marca registrada\0"
VALUE "OriginalFilename", "nomeexecutavel.exe\0"
VALUE "ProductName", "nomedoproduto\0"
VALUE "ProductVersion", "18.2.0\0"
VALUE "SpecialBuild", "Para Homologação\0"
VALUE "GitRevision", "790d79ee92af023d6beac953072c45b0385df17f\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0416, 1252
END
END
This .rc file is compiled through brcc32.exe.
In the project file the .RES file information generated by brcc32 is loaded.
{$R VersionInfoFactor.res}
After I do the build and install on a Windows machine in Portuguese, I can view the version information by right-clicking on the executable, selecting Properties, then Details.
So far, this is nothing new, it shows the data that is informed in the .rc file.
Now, if I install this same executable on a Windows machine in another language, I can no longer view this information.
Would anyone know the cause?
Your resource script provides version info for ONLY Portuguese and no other language. So, of course, a non-Portuguese machine won't display anything meaningful.
You need to provide multiple StringFileInfo blocks, one for each language you want to support. And you should have a block for US English, which is the fallback when a block for a specific language is not provided.
You should organize the blocks in this order, per Hierarchical Organization of Resources for Localization:
US English
Neutral cultures
Specific cultures
On a side note, you don't need to invoke brcc32.exe manually. The Delphi compiler can do that for you, if you include the .rc filename in the {$R} directive:
{$R VersionInfoFactor.res VersionInfoFactor.rc}

How can I automatically check for missing localizations in Xcode?

SourceFile.m
NSLocalizedString(#"Word 1", #"");
NSLocalizedString(#"Word 2", #"");
de.lproj/Localizable.strings
"Word 1" = "Wort 1";
"Word 2" = "Wort 2";
fr.lproj/Localizable.strings
/* Missing Word 1 */
"Word 2" = "Mot 2";
Is there a script or a compiler setting that will check that all localised strings are translated in all supported locales?
You can use diff on the list of keys to see what's missing
Here's a shell script (let's call it keys.sh) to print out the keys of a given .strings file, sorted to stdout:
#!/bin/sh
plutil -convert json "$1".lproj/Localizable.strings -o - | ruby -r json -e 'puts JSON.parse(STDIN.read).keys.sort'
You can then use it combined with the <(cmd) shell syntax to compare keys between two localisations; for example to compare your Base.lproj and fr.lproj:
diff <(keys.sh Base) <(keys.sh fr)
Go under "Edit Scheme > Options" and check the "Show non-localized strings" box.
When you Build and Run you'll able to see warnings on Xcode command screen.
if you localized string like below:
lblTitle.text = NSLocalizedString("Lorem Ipsum", "")
then Xcode should throw an error message on terminal like below:
ERROR Lorem Ipsum not found in table Localizable of bundle CFBundle ...
For storyboards, Xcode will throw a similar error.
Not the perfect solution for your problem. But you could uses following plugin to check localization strings while coding.
https://github.com/questbeat/Lin
Also, I use to export localization string table from an Excel file or Google Sheet as a practice. This will make things easier and reduce lot of mistakes.
Check my example on how you can achieve it
To sum up: you can create a Run Script under Build Phase in which you execute a bash script like suggested from #AliSoftware to compare your Localizable.strings and in case some keys are missing from one compared to the other you could either stop the build and output those missing keys as error or you could just output them as error and not let the build continue.

PC installer desktop shortcut and uninstall confirmation

Currently working with NSIS to create an installer for my PC game, was wondering if there is a way (some default command) to be able to do the 2 following things :
Prompt the user for confirmation when he uninstalls the game (I am currently doing it manually (AKA messagebox) but my problem is that it's always in English (I pretty much want the message to be localized, am wondering if there is a default option to prompt the user that would be localized by default, like the rest of the installer).
Ask to create desktop shortcut (again, I am doing this using the MUI_FINISHPAGE_SHOWREADME_TEXT, but my text isn't localised)
If there are no default ways of doing this what would be the best way to go to be able to localise those two sentences in my installer ?
There is a uninstall confirm page you can use:
!include MUI2.nsh
...
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
You can localize strings by using LangStrings:
!include MUI2.nsh
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_SHOWREADME
!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(FinishDeskLnkCheck)"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDeskLnk
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
!insertmacro MUI_LANGUAGE Swedish
LangString FinishDeskLnkCheck ${LANG_ENGLISH} "Create Desktop shortcut?"
LangString FinishDeskLnkCheck ${LANG_SWEDISH} "Bork Desktop bork bork?"
Function .onInit
!define MUI_LANGDLL_ALWAYSSHOW
!define MUI_LANGDLL_ALLLANGUAGES
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
; NOTE: Uninstaller langstring names must be prefixed with "un."
LangString ConfirmUninstMsg ${LANG_ENGLISH} "Kill it?"
LangString ConfirmUninstMsg ${LANG_SWEDISH} "Bork it?"
Function TranslateMsgBoxExample
MessageBox MB_YESNO "$(ConfirmUninstMsg)"
FunctionEnd
Function CreateDeskLnk
; CreateShortcut ...
Call TranslateMsgBoxExample
FunctionEnd
The text on the buttons in a MessageBox is going to use the current users UI language and cannot be translated...

DOS batch: get last folder from relative path

I have the following values in a DOS batch file (for example...):
..\Apple\Jones
..\Banana\Smith
..\Pear\Wilson
I need to extract the last name values ("Jones", "Smith", "Wilson") from each value. What one technique can I use that will always give me these substring values?
According to this topic : What is the best way to do a substring in a batch file?
I suggest you to use
%~n0
I already wrote a function for that. You give it any path and it returns you only it's filename or pathname. Works for any path: Url, Windows path, Unix path, etc...
Copy this function at the end of your batch script: (Instructions below)
rem ===========================================================================
:Name_From_Path
SetLocal
set _TMP_FOLDERNAME=%1
for %%g in ("%_TMP_FOLDERNAME%") do set _TMP_FOLDERNAME=%%~nxg
EndLocal & set _Name_From_Path=%_TMP_FOLDERNAME%
goto :EOF
rem ===========================================================================
Usage:
CALL :Name_Of_Path ..\Apple\Jones
ECHO %_Name_From_Path%
Result: Jones

Resources