How to add file in NSIS from headers - nsis

main_installer.nsi
This includes the header file that will install common files:
!include "C:\dir1\dir2\installer_helper_1.nsh"
And calls the function/macro:
${helper_1} $0
Where $0 is the return value indicating success.
installer_helper_1.nsh
This header file contains the function/macro ${helper_1} to add common files.
This function/macro contains the line:
File "C:\dir1\dir2\CommonFile1.txt"
How can I change this line such that the directory CommonFile1.txt is located in can be relative to the header file?
File "CommonFile1.txt"
The above line will not work as the compiler will look for the file in the same director as main_installer.nsi. I want the equivalent relative path such that it will look in the directory where installer_helper_1.nsh is located.

NSIS 3 has a ${__FILEDIR__} define you can use:
File "${__FILEDIR__}\CommonFile1.txt"

Related

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

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

Using Python to copy contents of multiple files and paste in a main file

I'll start by mentioning that I've no knowledge in Python but read online that it could help me with my situation.
I'd like to do a few things using (I believe?) a Python script.
I have a bunch of .yml files that I want to transfer the contents into one main .yml file (let's call it Main.yml). However, I'd also like to be able to take the name of each individual .yml and add it before it's content into Main.yml as "##Name". If possible, the script would look like each file in a directory, instead of having to list every .yml file I want it to look for (my directory in question only contains .yml files). Not sure if I need to specify, but just in case: I want to append the contents of all files into Main.yml & keep the indentation (spacing). P.S. I'm on Windows
Example of what I want:
File: Apes.yml
Contents:
Documentation:
"Apes":
year: 2009
img: 'link'
After running the script, my Main.yml would like like:
##Apes.yml
Documentation:
"Apes":
year: 2009
img: 'link'
I'm just starting out in Python too so this was a great opportunity to see if my newly learned skills work!
I think you want to use the os.walk function to go through all of the files and folders in the directory.
This code should work - it assumes your files are stored in a folder called "Folder" which is a subfolder of where your Python script is stored
# This ensures that you have the correct library available
import os
# Open a new file to write to
output_file = open('output.txt','w+')
# This starts the 'walk' through the directory
for folder , sub_folders , files in os.walk("Folder"):
# For each file...
for f in files:
# create the current path using the folder variable plus the file variable
current_path = folder+"\\"+f
# write the filename & path to the current open file
output_file.write(current_path)
# Open the file to read the contents
current_file = open(current_path, 'r')
# read each line one at a time and then write them to your file
for line in current_file:
output_file.write(line)
# close the file
current_file.close()
#close your output file
output_file.close()

Inno Setup preprocessor can read a file using FileOpen, but not using ReadIni

This is a clarification required to the existing post mentioned below
How to declare an Inno Setup preprocessor variable by reading from a file
Reading value from .txt file using FileOpen works perfectly fine, while reading .ini file using ReadIni returns an empty string.
The code for reading from txt file is:
#define VerFile FileOpen("common\GlobalConfig.txt")
#define AppVer FileRead(VerFile)
#expr FileClose(VerFile)
#undef VerFile
The txt file has the string Innovation.
The code for reading from ini file is:
#define AppVer ReadIni("common\GlobalConfig.ini", "Productname", "Product")
The content of the ini file is:
[Productname]
Product=Innovation
Both the files are in the same folder location.
The file is encoded with UTF-8 without BOM. I've checked with other types of encoding too, but it is returning only empty. I created with Notepad++.
Thanks in advance!
The relative paths in ReadIni are resolved to the current working directory, what particularly in Inno Setup IDE is not the script directory.
Use absolute paths by using SourcePath predefined variable:
#define AppVer ReadIni( \
SourcePath + "\common\GlobalConfig.ini", "Productname", "Product")
For FileOpen ISPP does that automatically, but not for ReadIni.
While not your case, another possibility is that there's something wrong with the INI file. It has to be UTF-8/ASCII without BOM or UTF-16 LE (with or without BOM).

Puppet-lint configuration file

Is there a way to disable checks in puppet-lint using a configuration file as it is in rubocop? The configuration file should be a txt file, a json file or other formats?
Yes, the file is called .puppet-lint.rc and should look like this:
--fail-on-warnings
--relative
--no-class_inherits_from_params_class-check
--no-documentation-check
--no-single_quote_string_with_variables-check
It's a list of arguments that you would normally pass as command line arguments. For all checks see documentation.

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

Resources