NSIS: Reading from a file at compile time - nsis

I want to read some values from a file (config.json) into some variables when I compile my nsis script.
How can I possibly do that?
Thanks in advance.

The !include command can include any file (at compile time) at the point where it is placed in the nsis script. But the included file must be compliant with the nsis syntax (e.g. it should !define some values).
The !execute command could help you: if you need absolutely to process a json file you could code a third-party batch command file to pre-process the json file and translate it into a suitable nsis file.

You can use !define to pass some value which can be used in compile time. For example lets imagine that you have got this code in you nsis source file:
!define PATHTOFILE "C:\thisfilewillbedeleted.ext"
Delete $PATHTOFILE
If you want to change this walue on compile time you can call nsis in this way:
makensis /DPATHTOFILE="C:\otherfiletodelete.ext"
[EDIT]
If you got *.json file which is generated using external tool and you must use this kind of file I will suggest you to use some building system, for example ant. You can create build.xml which read, parse data from json file and then write those data to *.nsh file. I think it will be better and cleaner than do it all in nsis script.

If you just need to parse your json file on runtime, you can use !define with the /file option:
!define /file OPTIONS json.txt
It will define OPTIONS with the content of json.txt.
If you want to utilize your json file in compile time to alter the generated exe, then you need some kind of precompiler, which is what you're actually doing.

You may use the !searchparse command with the /file switch.
Example :
# search filename.cpp for a line '#define APP_VERSION "2.5"' and set ${VER_MAJOR} to 2, ${VER_MINOR} to 5.
!searchparse /file filename.cpp `#define APP_VERSION "` VER_MAJOR `.` VER_MINOR `"`

Related

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.

check for file existence using nmake and delete it

I am using Windows version of NMAKE. I would like to check for file existence in a make file. If it exists I need to delete it. Here is my code:
!IF EXIST ("C:\ABC.XML")
#del ABC.XML
!ELSE
#echo "FILE DOESN'T EXIST
!ENDIF
The above code is not working. I could not figure it out the problem. Please help.
Your code doesn't work because !IF, !ELSE and !ENDIF are a preprocessing directives and the result of preprocessing must produce a valid makefile. Commands are only allowed as part of what Microsoft calls a description block which are required to start with a dependency line with one or more targets and zero or more dependents.
You can get around this by executing your commands during the preprocessing stage by including them in a preprocessing directive surrounded by brackets ([]). Something like this:
!IF EXIST(C:\ABC.XML)
! IF [del C:\ABC.XML]
! ENDIF
!ELSEIF [echo FILE DOESN'T EXIST]
!ENDIF
The second !IF and the !ELSEIF directives are used to provide a context for the commands so they're executed during the preprocessing phase.
However I think you'd probably be better moving the del command to a description block where it's actually needed. For example if file ABC.XML needs to be deleted before it can be rebuilt, use something like this:
ABC.XML: ABC.CSV
-rem The csv2xml translator requires that the XML file not already exist
-#del ABC.XML 2> NUL
csv2xml ABC.CSV ABC.XML

How to modify text value in Bat file using Nsis script

I have builded Nsis script successfully.I have bat file in my project.Inside bat file i have two variables with default values as follows
JVM_DLL=c:\program Files\java\jre\bin\client\jvm.dll
Home_path=c:\opt\projectName
If the user wants to modify the value for JVM_DLL and Home_path that should be written in batch file.How to do this? I donot know how to write in batch file using Nsis script?
I have tried following codes.but its not working
StrCpy $JVM_DLL "jre\bin\client\jvm.dll"
${ConfigWrite} "$INSTDIR\resource\batch.bat" "JVM_DLL" "=$JVM_DLL" $R0
${ConfigWrite} "$INSTDIR\resource\batch.bat" "HOME_PATH" "=$INSTDIR" $R0
thanks
If you have defined the 2 values in the .bat file that is also launching makensis.exe, use the /D command line switch to define those values for the nsis script.
In your example, given your 2 .bat variables:
makensis.exe /DJVM_DLL=%JVM_DLL% /DHome_path=%Home_path% yourscript.nsi

Accessing command line arguments in NSIS

I am trying to make my setups scripts modular. I am calling setup exe's from within main setup script based to the requirements. I want to pass command line arguments to the exe being called. Can someone please tell me how to access the command line arguments in the script being called.
Thanks in advance.
you can use GetOptions function (FileFunc.nsh must be included above). Following example shows p parameter reading; its value is saved into the variable. $CMDLINE is your command line (absolute or relative, as you called) containing also your parameters.
!include FileFunc.nsh
Var variable
${GetOptions} $CMDLINE "/p" $variable
Try to get options from Command line by their name:
http://nsis.sourceforge.net/Get_command_line_parameter_by_name

nmake: can a batch file run as part of a make command block, affect the environment of the nmake.exe process?

I think in nmake if I do this:
example :
set value=77
echo %%value%%
The result will display 77 on the console.
Is there a way for me to invoke a .cmd or .bat file that will affect the environment of the nmake.exe process? Suppose I put the statement set value=77 in a file called "setvalue.cmd". Then change the makefile to this:
example :
setvalue
echo %%value%%
I get:
%value%
Alternatively, if there's a way to set a macro within a command block, that would also work. Or, a way to set the value of a macro from a batch file, even outside a command block.
You can create an nmake snippet during makefile pre-processing, and read that in. Assuming batch.cmd outputs valid nmake syntax, then
!if [batch.cmd >makefile.auto]
!error *** Could not create makefile.auto
!endif
!include makefile.auto
You should ensure batch.cmd sets %errorlevel% appropriately (e.g., exit /b 22).
makefile.auto can contain anything, but you would probably want stuff like value=77. A couple of points:
Dereference value using nmake syntax ($(value))
You can pass parameters to batch.cmd if necessary ([batch.cmd $(OBJECTS) >makefile.auto])
No, I don't think so.

Resources