Write russian symbols in ini file with NSIS installer - nsis

I have several UTF8-BOM ini-files and using Unicode nsis installer.
Using WriteINIStr is working great with latin symbols, but russian symbols are not displayed.
For example this code is not working:
WriteINIStr $File "TestSection" "Test" "Тест"
I have a few thoughts about encoding file into UTF16 and backwards, but I don't think that's the right path.

If the .ini has a UTF-16LE BOM the Windows ini functions will write to the file with UTF-16 encoding.
FileOpen $0 $INSTDIR\file.ini a
FileWriteUTF16LE /BOM $0 ""
FileClose $0
WriteIniStr $INSTDIR\file.ini foo bar "${U+2115}SIS"
As long as other programs that access this file also uses the standard Windows ini functions this will work. If the other programs uses custom parser functions that require UTF-8 then this will not work and you have to convert the file encoding.

Related

NSIS AccessControl::GrantOnFile permission failing

I am trying to create and set a directory with NSIS and the accessControl plugin like the following:
CreateDirectory "$APPDATA\${productName}"
; create fileResources directory
CreateDirectory "$APPDATA\${productName}\fileResources"
AccessControl::GrantOnFile "$APPDATA\${productName}\fileResources" "Everyone" "FullAccess"
Pop $0 ; get "Marker" or error msg
StrCmp $0 "Marker" Continue
MessageBox MB_OK|MB_ICONSTOP "Error setting access control for $APPDATA\${productName}\fileResources: $0"
Pop $0 ; pop "Marker"
Continue:
Pop $0
I am receiving the following on $0 what is that response?
I want to make a folder readable and writable by the installed program
I'm guessing that you are building a Unicode installer using NSIS v3 and that you put the wrong plugin in the plugins subdirectory, that is why the result looks chinese.
To install a plugin correctly you need to put the ANSI .dll in NSIS\Plugins\x86-ansi and the Unicode .dll in NSIS\Plugins\x86-unicode.

Copying files from a folder with a pattern

As part of my installer I'm extracting a JRE which is in a folder that varies name (i.e. jre1.8.0_74). I'm trying to do that with a pattern, but it can't find it. I tried something like this:
SetOutPath "$INSTDIR\${APPDIR}\jre"
${If} ${RunningX64}
File /nonfatal /a /r "${SrcDir}\jre\jre_64\jre*\*.*"
${Else}
File /nonfatal /a /r "${SrcDir}\jre\jre_32\jre*\*.*"
${EndIf}
But found no files. I basically want to skip this "unknown" folder name to make it easier starting my application, etc.
I know it's a NSIS newbie basic mistake somewhere :P
Any idea?
When something is not known at compile-time you must use !system to execute a batch file or something else that is able to create a text file with the desired NSIS instruction that you later can !include.
For filesystem wildcards you can probably get away with just using dir or for:
!macro InvokeNSISCommandOnWildcardFolder parentdir wildcard commandprefix commandsuffix
!tempfile _InvokeNSISCommandOnWildcardFolder
!system 'for /D %A in ("${parentdir}\${wildcard}") do #(^>^> "${_InvokeNSISCommandOnWildcardFolder}" echo ${commandprefix}${parentdir}\%~nxA${commandsuffix})'
!include "${_InvokeNSISCommandOnWildcardFolder}"
!delfile "${_InvokeNSISCommandOnWildcardFolder}"
!undef"${_InvokeNSISCommandOnWildcardFolder}"
!macroend
Section
SetOutPath "$INSTDIR\${APPDIR}\jre"
!insertmacro InvokeNSISCommandOnWildcardFolder "${SrcDir}\jre\jre_32" "jre*" 'File /nonfatal /a /r "' '\*.*"'
SectionEnd
Because my example here just uses !system to invoke "DOS" commands directly there are some restrictions on the strings passed to this macro and <, >, (, and ) might have to be escaped.

get hard disk drive name in which windows OS installed using NSIS

I need to get hard disk drive letter like C: or D: or any in which the OS is installed on any windows.
Kindly help me get out of this.
Section
StrCpy $0 $sysdir 3
DetailPrint $0
SectionEnd
$SYSDIR is the Windows system directory (usually C:\Windows\System or C:\WinNT\System32, but that's detected at runtime).
StrCpy has the syntax StrCpy user_var(destination) str(source) [maxlen] [start_offset] where maxlen and start_offset are optional.
So the code above, copies the first three letters from $SYSDIR into the $0 variable.

How do I conditionally compile an NSIS script based on commandline parameters?

I'm trying to generalize a setup file by externally passing the version number. I want to be able to do this:
makensis myscript.nsi parameter=value
and then read the parameter within the script, so that using the same script I can generate differently versioned executables. I found this & this, but they seem to be for passing commandline parameters to the generated setup.exe. Is this possible, and how?
You can add symbols to the globally defined list from the command line using the /D switch:
makensis /DMyVersion="1.0.1" install.nsi
Then you can use them using the ${} syntax:
!ifdef MyVersion
StrCpy $Version "${MyInstallerName}"
!else
StrCpy $Version "1.0.0"
!endif
Also of possible interest is the GetVersion plugin discussed in this SO question: NSIS - put EXE version into name of installer

Install from dynamic location

I have 2 versions of the same exe file for my project. The installer is supposed to pick one of the 2 versions depending on some conditions.
In a normal case i would do File executable\myExe.exe. Because i now have 2 versions of the file, i would have to do something like File "${ExeSourcePath}\myExe.exe", and $ExeSourcePath is determined by checking various conditions. When compiling this code i get
File: "${ExeSourcePath}\myExe.exe" -> no files found.
Anyone knows why? I'm only allowed to use fixed paths with the File command or am i doing something wrong?
${ExeSourcePath} is a precompiler define and $ExeSourcePath is a variable used at runtime, the File command can only use precompiler defines.
There are two ways you can handle this:
A) Include both files and decide at runtime based on the users system or choices made during install:
!include LogicLib.nsh
Section
ReadRegStr $0 HKLM "Software\foo\bar" baz
${If} $0 > 5
File "c:\myproject\version2\app.exe"
${Else}
File "c:\myproject\version1\app.exe"
${EndIf}
SectionEnd
B) Only include one file based on command line passed to makensis (/Dusev2 app.nsi) or something on your system:
Section
!define projectroot "c:\myproject"
!searchparse /noerrors /file ....... usev2 ;Or you can use !system etc
!ifdef usev2
File "${projectroot}\version2\app.exe"
!else
File "${projectroot}\version1\app.exe"
!endif
SectionEnd

Resources