NSIS variable value get set concerns - nsis

Well, from few years I'm working with NSIS installers and I treat all variables as string in my scripts. Somewhere I read about this, that NSIS internally treat all variables as string, but don't know the exact fact.
Now my query is whenever we are copying some values into some variables or checking the variable's value using logic statements what should be the ideal way to do it. Let me show you an example what I'm talking about.
StrCpy $1 "Some string goes here"
StrCpy $2 999
${If} $1 == "String to match here"
${If} $2 == 999
${If} $2 == "999"
I guess I have no other option for StrCpy $1 case as there I'm copying string into a variable, but for case StrCpy $2, perhaps I can write StrCpy $2 "999" as well. Same thing goes for If statements.
I would like to know the correct convention for NSIS scripting.

Yes, internally everything is stored as strings and they converted to numbers when doing a number operation. Strings that cannot be converted to numbers are treated as 0.
StrCpy $2 999 and StrCpy $2 "999" is exactly the same thing, the quotes are only required when the string has spaces and the quotes are removed by the compiler automatically even when there are no spaces. This also means that ${If} $2 == 999 and ${If} $2 == "999" is the same.
When comparing you should use =, <>, <, <=, >= and > for numbers and == and != for strings.
${IfThen} 0x29A = 666 ${|} DetailPrint "True" ${|} ; 0x29A is 666 in hex
${IfThen} 0x29A == 666 ${|} DetailPrint "This will never print" ${|}

Related

Deregistering a font with NSIS

When I try to uninstall a font like that...
Section "un.Uninstall"
StrCpy $FONT_DIR $FONTS
!insertmacro RemoveTTFFont "$FONTS\Vani.ttf"
!insertmacro RemoveTTFFont "$FONTS\Vanib.ttf"
SendMessage ${HWND_BROADCAST} ${WM_FONTCHANGE} 0 0 /TIMEOUT=5000
SectionEnd
I get the following error message:
Error in macro GetFileNameCall on macroline 2
Error in macro RemoveTTFFont on macroline 9
(...) aborting process
In other words, there's something wrong with the following section in the FontReg.nsh file:
!ifmacrondef GetFileNameCall
!macro GetFileNameCall _PATHSTRING _RESULT
Push `${_PATHSTRING}`
Call GetFileName
Pop ${_RESULT}
!macroend
!endif
!ifndef GetFileName
!define GetFileName `!insertmacro GetFileNameCall`
Function GetFileName
Exch $0
Push $1
Push $2
StrCpy $2 $0 1 -1
StrCmp $2 '\' 0 +3
StrCpy $0 $0 -1
goto -3
StrCpy $1 0
IntOp $1 $1 - 1
StrCpy $2 $0 1 $1
StrCmp $2 '' end
StrCmp $2 '\' 0 -3
IntOp $1 $1 + 1
StrCpy $0 $0 '' $1
end:
Pop $2
Pop $1
Exch $0
FunctionEnd
!endif
Can someone, if not tell me how to fix the bug, at least point me in the right direction?
It would be useful for the community as many have had this problem but no one has solved it yet, like here - http://forums.winamp.com/showthread.php?t=245701
I haven't received any answers unfortunately, but I must share the solution I came up with, since I saw that lots of people have had the same problem.
There is a bug in macros to remove fonts, namely "RemoveTTF", "RemoveTTFFont" and similiar sounding ones in the following files : FontReg.nsh, FontRegAdv.nsh. All of them use the same function called "GetFileNameCall" which causes the error. The problem with this function is that it sees "FontName" and "FontFileName" as the same item! As a matter of fact, font file name differs from font name. I solved the problem by copying the needed code from FontRegAdv.nsh and replacing FontFileName and FontName variables with the actual font file names and font names.

NSIS code if-else to stack operation

I always get confused when it comes to nsis stack operation. Now I'm writing a small piece of code for trimming trailing space from a string.
Input:
C:\Program Files (x86)\COMPANY\ or C:\Program Files (x86)\COMPANY
Output:
C:\Program Files (x86)\COMPANY
Working code - with normal if-else
!define TrimPath '!insertmacro "_TrimPath"'
!macro _TrimPath _FOLDERPATH
StrCpy $0 `${_FOLDERPATH}` 1 -1
${If} $0 == "\"
StrCpy $1 `${_FOLDERPATH}` -1
StrCpy `${_FOLDERPATH}` $1
${EndIf}
!macroend
Wrong code - with stack operation
!define TrimPath '!insertmacro "_TrimPath"'
!macro _TrimPath _FOLDERPATH
Exch $0
StrCpy $2 $0 1 -1
StrCmp $2 "\" +2 +1
StrCpy $1 $0 -1
StrCpy $1 $0
Pop $0
Exch $1
!macroend
Can anyone correct me and point me whats wrong?
I think you're trying to use a macro as a function. Some comments/questions/hints:
Why are you using Exch which swaps the value in the top of the stack instead of using _FOLDERPATH ?
Are you pushing the parameter in the stack before calling the macro? Something like:
push $path
${Trimpath}
Pop $0 restores the value of $0 but then you call Exch $1 which will swap the value in top of the stack (unknow value, maybe the stack is empty) with $1. Why?? If you want to save the result in the stack, just push $1.

NSIS substring by index

Is there any function which can cut string by letter index? I mean the X letters from the end?
!define myString "abcdefg"
I need to get for ex. "efg"
i tried to do that with nsis strings functions but didnt found what can help me.
${StrStr} and all the other functions doesnt do the work
Thanks
This is very simple. Actually, you don't have any dedicated function to do that, but you StrCpy can do that with 3rd and 4th arguments.
The format is going like that:
user_var(destination) str [maxlen] [start_offset]
And the usage for you case, is:
StrCpy $0 $myString "" -3
$0 will be: efg
More information about StrCpy function, can be found out there: http://nsis.sourceforge.net/Reference/StrCpy
StrCpy $0 "abcdefg" "" -3 ; variable $0 now has the last 3 letters
See the manual for more info about StrCpy

Extra newline characters between items in a drop down menu

I am creating a installer using the nsis installer. In that installer I need to put a drop down menu for currency selection.
The text file which I am using is not being properly inserted, the newline character that I am using to separate the currencies is actually taking a character in the installer, while for the license page I am using the same extension for the text file which I am putting there and it is working fine over there.
How to filter out those extra characters?
Without a sample file I had to guess what the actual problem is, hopefully its just the newlines:
Page custom mycustompage
!include nsDialogs.nsh
!include TextFunc.nsh
Function mycustompage
nsDialogs::Create 1018
Pop $0
; I don't have a list of things so I generate one on the fly for this example:
!tempfile MYLIST
!appendfile "${MYLIST}" "Foo$\r"
!appendfile "${MYLIST}" "Bar$\r$\n"
!appendfile "${MYLIST}" "Baz$\n"
File "/oname=$pluginsdir\thelist.txt" "${MYLIST}" ; include list in installer
!delfile "${MYLIST}"
${NSD_CreateDropList} 10u 10u 50% 100% ""
Pop $0
FileOpen $1 "$pluginsdir\thelist.txt" r
loop:
FileRead $1 $2
IfErrors endloop
${TrimNewLines} $2 $2
StrCmp $2 "" loop ; skip empty line
${NSD_CB_AddString} $0 $2
goto loop
endloop:
nsDialogs::Show
FunctionEnd

Reading a text file into a text box using nsdialog? NSIS

I am new to NSIS scripting installer. I need to create a TextBox with Multiline support, in Custom page. Need to read a text file and set the text content to TextBox. Please find my code block below:
StrCpy $3 ""
FileOpen $4 "C:\Users\Surya\Desktop\Installer\License.txt" r
loop:
FileRead $4 $1
StrCpy $3 "$3$1" ; append the line and copy it to another variable
IfErrors +1 loop
FileClose $4
${NSD_SetText} $ctrlTextBox "$3"
The above code able to read only 8119 characters only, but my file contains 30,000+ characters.
Please help me to read the large file and set the content to TextBox.
Thank You
You can fill a textbox with a little bit of text at the time (inside your loop) if you use EM_SETSEL (twice) to move the caret to the end and then use EM_REPLACESEL to append text.
If you can use a rich edit box instead then use some code I wrote a long time ago, you can find the forum thread here...
Edit:
As long as the textbox is empty when you begin you don't have to deal with the caret:
function custcreate
nsDialogs::Create 1018
Pop $0
nsDialogs::CreateControl ${__NSD_Text_CLASS} ${__NSD_Text_STYLE}|${ES_MULTILINE}|${WS_VSCROLL}|${ES_READONLY} ${__NSD_Text_EXSTYLE} 0 0 100% 50u ""
Pop $0
FileOpen $4 ${__FILE__}" r
loop:
FileRead $4 $1
SendMessage $0 ${EM_REPLACESEL} 0 "STR:$1"
IfErrors +1 loop
FileClose $4
nsDialogs::Show
functionend

Resources