NSIS Invalid command: IDOK/IDCANCEL - nsis

I am able to use MessageBox MB_OK and MB_OKCANCEL, but compiler throws an error when I try to use IDOK and IDCANCEL.
My NSIS version is 2.46.

The basic syntax for calling MessageBox with OK and Cancel buttons is:
MessageBox MB_OKCANCEL "my message" IDOK label_for_ok IDCANCEL label_for_cancel
label_for_ok:
;do some stuff
goto end_label ;for not executing the "cancel" branch
label_for_cancel:
;do some other stuff
end_label:
In this case, as the ok case is just after the Messagebox, you can remove the IDOK label_for_ok and the label at the following line.

(Sorry for this little self promo)
You can use my tool called Visual & Installer (http://www.unsigned-softworks.sk/visual-installer/) to check correct syntax and usage in NSIS script in Visual Studio to avoid such situations:
As you can see it has a really nice syntax highlighting, when you move over some command a tooltip is shown and (if you look at Error List) you can see the PROGRAM_NAME was recognized as unused because it was not defined in the script snippet.

Related

Compare 'installed-version'versus 'to-be-installed-version'

Have been working with NSIS (v3.05) for a few weeks. Does what it needs to do. I have been chasing the following problem for a few days and have not been able to comprehend it completely.
Problem statement:
Compare two (2) versions with each other. Many ways to implement. I chose the following:
1st 'version' (string) is retrieved from the currently installed versions .txt file via (function) LineRead (!include TextFunc.nsh) like this:
IfFileExists "C:\$PROGRAMFILES64\...\VERSION.txt" 0 +31 # Open the file and perform N FileRead
DetailPrint "VERSION.txt found!"
${LineRead} "C:\$PROGRAMFILES64\...\VERSION.txt" "7" $4 # $4 = '1.x.y.z' (for example)
2nd 'version' is retrieved with following code:
!getdllversion "C:\...\application_name.exe" expversion_
StrCpy $7 ${expversion_} # pass the define string 'expversion' to $7
As last part I use following code for comparison of $4 and $7:
${VersionCompare} $4 $7 $R0
This can only work as I know for sure that '$4' (version string #1) and '$7' (version string #2) are correct inputs for VersionCompare (output: $R0)
Question: Is there a way to display (for test/check) the content of $4 (# compile time) in order to know for sure var $4 contains the correct string to be passed to function 'VersionCompare'? (tried 'DetailPrint $4'; does not resolve into the expected string (retrieved by function 'LineRead'). (I know that 'DetailPrint' only displays during executing the installation '.exe. file So is makes sense not seeing that # compile time.)
Output from MakeNSIS:
IfFileExists: "C:\$PROGRAMFILES64\...\VERSION.txt" ? 0 : +31
DetailPrint: "VERSION.txt found!"
!insertmacro: LineReadCall
!insertmacro: end of LineReadCall
DetailPrint: "The version number of the currently installed app: $4"
How-To get $4 resolve into the version string (for testing purposes) during compile time)?
Question number 2:
I use the preprocessor command '!GetDLLVersion' in a function to retrieve version number of the to be installed version of the 'app' (via The NSIS Installer...). MakeNSIS displays resolving the version correctly:
Function: "VersionRetrievalBinary"
!getdllversion: C:\1_SW_dev\...\app.exe (1.8.47.5)->(expversion_<1..4>)
Question: What exactly is 'expverion_'?; a var or a define? If a define (which I read here => Reference/!getdllversion), do I need to define it in my script as follow?:
!define expverion_1 " " # Major; single digit
!define expverion_2 " " # Minor; 2-digit
!define expverion_3 " " # Build; 3-digit
!define expverion_4 " "# Revision; 3-digit
Being unsure what 'expversion_' exactly is and operates/works MakeNSIS throws following warning that -I think- indicates clearly something is incorrect:
warning 6000: unknown variable/constant "{expversion_}" detected, ignoring (C:\1_SW_dev\...\app_client.nsi:295)
The worrying part is the word 'ignoring' in the MakeNSIS compiling message. Can I conclude from above mentioned warning message that assigning the string derived from the (define?) with name "expversion_" is not passed to var $7 by means of command:
StrCpy $7 ${expversion_}
Following MakeNSIS message (# compile time) appears to confirm this:
StrCpy $7 "${expversion_}" () ()
It appears to resolve empty (unsure if I read this MakeNSIS message correctly).
Although having learned a lot wrt NSIS (and liking it) and gone through most of the relevant documentation I do not get my head around this one.
Thnx in advance for solving this specific piece of the puzzle.
Have solved the puzzle myself.
The solution to a version comparison is rather 'simple'. The essential parts herewith: (add to .onInit)
Create a function (e.g. name 'VersionComparison')
Read local version from registry
'Read' installation version from binary (e.g. .DLL or .exe)
Use VersionCompare (!include WordFunc.nsh) to perform the actual comparison.
I'll tackle the !getdllversion issue first. It extracts the 4 16-bit numbers from the start of the version info block and stores them in 4 defines. It simply uses the name you pass in plus a number when naming the defines.
!getdllversion "$%windir%\explorer.exe" foo
!warning ${foo2} ; This prints the minor version
There is no specific number of digits as expected by your comments. Each of the 4 numbers go from 0 to 65535.
You can do basic verification of these numbers at compile time:
!if ${foo1} < 1
!error "Major version must at least be 1, we don't ship beta software :) "
!endif
The 2nd problem is harder to solve. Variables can only be expanded when the installer is running. The only option is to actually generate and run a "installer" from inside your main .nsi:
!makensis vertest.nsi = 0
!execute '"$%temp%\vertest.exe" /S' = 0
!defile "$%temp%\vertest.exe"
where vertest.nsi would look something like
OutFile "$%temp%\vertest.exe"
RequestExecutionLevel user
SilentInstall silent
Section
Do version test here and Goto..
fail:
Abort
success:
SectionEnd

Where can I add command line in the NSIS script

I would add some command line to customize my NSIS intaller. I already read some topics, I know I must use ${GetParameters} and ${GetOptions}. But the NSIS script is very long do I put him somewhere in the OnInit function or in a section at the beginning of the script ?
I want, for example, to add an --quiet command line which display all the pages except the license( something which seems to /S), I want to try something like that:
Var DisplayAllPages
Var DisplayLicense
${GetParameters} "quiet"
${GetOptions} "quiet" "--quiet"=DisplayLicense
But I don't Know where can I write
You can use ${GetParameters} and ${GetOptions} in any function and/or section.
Only .onInit and sections are executed when the installer is started with /S so if you wish to turn silent mode off you need to put the code in .onInit.
If you are storing the result in a global variable then .onInit is also a good place to call them so that the information is available to the rest of the installer.

Error when trying to use File inside ${ForEachIn}?

I have the following code block inside the .onInit function of my NSIS script.
; Split the supplied artifacts array.
nsArray::Split ARTIFACT_ARRAY "${ARTIFACTS}" ";"
${ForEachIn} ARTIFACT_ARRAY $R0 $R1
File ${IVY_ROOT}\"$R1"
${Next}
The ${ARTIFACTS} is a passed in property from ANT at NSIS compile time and is basically a comma seperated list of files. When I attempt to compile the script I get the error below.
[exec] File: "C:\My_Workspaces\WEnDL\\deployments\ivy\"$R1"" -> no files found.
[exec] Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
[exec] /oname=outfile one_file_only)
[exec] Error in script "C:\My_Workspaces\WEnDL\/deployments/selections.nsis" on line 394 -- aborting creation process
Any pointers appreciated.
You cannot use variables in File instructions because variables are only evaluated on the end-users system. The same is true for plug-ins. You need to stick with ${defines} and the instructions starting with ! when parsing at compile-time.
The best option is letting your build system generate a .nsh with the File instructions if possible:
Section
SetOutPath $InstDir
!include "generatedfilelist.nsh"
SectionEnd
Another option is to call external tools or batch-files with !system and let them parse the list and generate the .nsh.
Finally, in NSIS v3 it might be possible to pull this off with macro recursion and !searchparse+!searchreplace but the available recursion depth is limited so it might not work depending on the number of files in your list.

NSIS scripting file error while extracting a zip file

When I am using the following NSIS script:
ZipDLL::extractall "C:\Users\sid008\Desktop\NSISTutorials.zip" "F:\nist" "<ALL>"
then I am getting the below error:
!define: "MUI_INSERT_NSISCONF"=""
Changing directory to: "C:\Users\sid008\Desktop"
Processing script file: "C:\Users\sid008\Desktop\Ext1.nsi" (ACP)Error: Can't add entry, no section or function is open!
Error in script "C:\Users\sid008\Desktop\Ext1.nsi" on line 1 -- aborting creation process
Any ideas on what goes wrong?
As the error says: You need to use this line inside Function or Section.
The correct usage:
Section "Section name"
ZipDLL::extractall "C:\Users\sid008\Desktop\NSISTutorials.zip" "F:\nist" "<ALL>"
SectionEnd
Function Func
ZipDLL::extractall "C:\Users\sid008\Desktop\NSISTutorials.zip" "F:\nist" "<ALL>"
FunctionEnd

Exec not working in NSIS installer

I am new to NSIS i am trying to execute an executable while installation similar to pre request. I tried the below code which copies the exe to the installation path but it is not executing it.
Section "example" example
SetOutPath "$INSTDIR"
File "setup.exe"
Exec "$INSTDIR\setup.exe"
BringToFront
SectionEnd
The answer from Seki is mostly correct, I'd just like to add that the correct syntax for Exec/ExecWait is always Exec '"c:\path\app.exe" param1 "par am2" param3'
Parameters are of course optional but the path to the app should always be quoted, not just because in your case where $INSTDIR could contain spaces but at least on Win9x it will fail no matter what if you don't quote (According to the NSIS manual)
If the spaces/lack of quotes is not the issue then there are a couple of other things you might want to look into:
$OUTDIR is the working directory for the new process (SetOutPath sets this)
Missing dll's etc (Check with Process Monitor)
Do the $INSTDIR variable maps to a directory whose name contains spaces? If so, you should add simple quotes to include the double quotes into the Execargument :
Exec '"$INSTDIR\setup.exe"'

Resources