NSIS - How to install multiple files with similar folder structures using a single command? - nsis

Problem
I have multiple files in very similarly structured folders that I want to install in one common folder.
I can do this by manually specifying each file I want to add, like so:
SetOutPath "$INSTDIR\Final\Destination"
File /r ".\ParentFolder\Folder1\Same\Path\For\All\Thing1.ext"
File /r ".\ParentFolder\Folder2\Same\Path\For\All\Thing2.ext"
File /r ".\ParentFolder\Folder3\Same\Path\For\All\Thing3.ext"
File /r ".\ParentFolder\Folder4\Same\Path\For\All\Thing4.ext"
File /r ".\ParentFolder\Folder5\Same\Path\For\All\Thing5.ext"
However, there are 50+ of these files, and they are likely to change, so I'd prefer to do this in a way that won't require editing the NSIS in the future.
What I have Tried
I tried putting in wildcards, like so:
SetOutPath "$INSTDIR\Final\Destination"
File /r ".\ParentFolder\*\Same\Path\For\All\*.ext"
However, I get the message
File: ".\ParentFolder\*\Same\Path\For\All\*.ext" -> no files found.
Question
Is there something wrong with using multiple wildcards * in my File query?
What would be the correct way to query multiple files in different folders?

You can't put wildcards anywhere, only in the filename unfortunately.
What you can do however is to use !system to execute a batch file (or any other command or application) that writes NSIS instructions to a file you can !include:
Section
SetOutPath $InstDir
!tempfile folders ; temporary .nsh
!system 'for /D %A in (.\ParentFolder\*) do #>>"${folders}" echo File /r "%~A\Same\Path\For\All\*.ext"'
!include "${folders}"
!delfile "${folders}"
SectionEnd

Related

Fail to copying file in NSIS?

For copy file i use (code below) its work properly.
Section "one"
CreateDirectory $EXEDIR\dst
CopyFiles $EXEDIR\*.* $EXEDIR/dst
SectionEnd
When i use $PROGRAMFILES(only change the destination path) it create directory but copy doesn't work.
Section "two"
CreateDirectory $PROGRAMFILES\dst
CopyFiles $EXEDIR\*.* $PROGRAMFILES/dst
SectionEnd
where is the problem?
/ is not the path separator on Windows, use \. / is supported in a lot of places but not everywhere.
It might also be failing if you don't have write access to that folder so make sure you have RequestExectionLevel Admin in your script.
The only way to know for sure is to monitor the installer with Process Monitor...

Search for a file and open the path in CMD

I would like to achieve the following in CMD:
Will search for a specific filename - This I know how to do, with dir /s filename
Once found it will bring me to that path.
Example: I am now on C:\, if that file was found in C:\test then it will open C:\test in command prompt.
Alternatively, I would like just to copy the found file to a path I will specify. I just don't know how to do it, since I don't know the path where the file will be stored (it's different every time).
Thanks in advance!
I'm a liitle confused with your question but I will try to walk you through a batch code I wrote to help you with this.
dir /b /s "test.txt" > "%userprofile%/Desktop/result.txt"
::find the file path to the file you want to find and insert it in a .txt file
::you made called result.txt (also %userprofile% is a variable that brings you to
::your user directory ex C:/users/admin)
for /F "tokens=*" %%A in (%userprofile%/desktop/result.txt) do (
set var1=%%A
)
::set the variable var1 equal to the first (well... only) line in the file.
::I could explain what that for loop means in detail but just remember that %%A
::is a variable set from what was found when looping through the result.txt.
xcopy /s "%var1%" "C:/wherever/you/want/it/to/go"
did this help??

How to use File /r without recursing input directories

I have a directory structure which looks like this:
parent-dir
XXX
file.txt
YYY
file2.txt
CCC
XXX
file3.txt
I currently use File /r XXX to recursively get parent-dir\XXX but because /r also causes File to search the input directories recursively I also get all of parent-dir\CCC\XXX.
I realize I could CreateDirectory XXX and SetOutputPath XXX and use File /r XXX\* and then SetOutputPath back but I don't want to have to do that every time I use File /r
Is there a safe way to use File /r which will not grab unintended things which might get added to parent-dir in the future?
For that problem of File /r that could get unexpected files, I have made the following macro:
; SlurpSubDir : include a file pattern from a directory
!macro SlurpSubDir args parentSrcDir subDir pattern parentDstDir
SetOutPath "${parentDstDir}\${subDir}"
File ${args} "${parentSrcDir}\${subDir}\${pattern}"
SetOutPath "${parentDstDir}"
!macroend
!define SlurpSubDir "!insertmacro SlurpSubDir"
That I call like this to get the whole perl subdirectory from ${InstSrcFiles} that is the directory where the setup master files are located, with exclusion of possible .svn directories, and the files will be installe into $INSTDIR:
${SlurpSubDir} "/r /x .svn" "${InstSrcFiles}" "perl" "*.*" "$INSTDIR"

NSIS: Reading from a file at compile time

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 `"`

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

Resources