NSIS - File /x doesn't exclude files/directories as claimed - directory

I have a directory structure that needs to be added to the installer. I have 3 different versions of my install script, and one of them being an upgrade script, requires excluding a certain file and a subdirectory within my install directory.
So I do the following:
File /r /x ${InputDir}\data\someFile.xml /x ${InputDir}\data\derbydb\runtime\*.* ${InputDir}\*.*
The xml file and the derbydb directory are already present (since this is an upgrade) and hence I don't want to overwrite them. Yet on running the installer I clearly see that both files are overwritten, and moreover viewing the generated setup.exe with 7zip shows that they got added as well. One may as well have just called
File /r ${InputDir}\*.*
So what's going wrong here? I wish NSIS would have better documentation or list caveats with
their command parameters/syntax. (/rant)

NSIS manual (http://nsis.sourceforge.net/Docs/Chapter4.html) section 4.9.1.5 File contains the following:
Use the /x switch to exclude files or directories.
I tried to use different variants, but only one worked:
SetOutPath $INSTDIR
File /r /x Config ..\MyProgram\*.*
where "Config" is a directory "MyProgram\Plugins\Config".
NSIS searches only by name and it will be wrong to set any subfolders (e.g. "/x Plugins\Config" or "/x $INSTDIR\MyProgram\Plugins\Config\"). There is one lack: if you have the same folders in different directories, using the /r switch, both matching directories and files will be searched.

I find that
File /x "${DIRECTORY}Foo.img" "${DIRECTORY}*.img"
does NOT exclude Foo.img at compilation time - it is included with the other .img files.

Finally cracked it after pulling some of my hair out...
First exclude the whole sub directory from the *.*
File /r /x "subfolder" "C:\App\bin\*.*"
then change your output directory in to your subfolder...
SetOutPath "$INSTDIR\subfolder"
then exclude the xml files...
File /r /x "*.xml" "C:\App\bin\subfolder\*.*"
and then set the output path back to how it was...
SetOutPath "$INSTDIR"
so it should look somthing like this...
SetOutPath "$INSTDIR"
File /r /x "subfolder" "C:\App\bin\*.*"
SetOutPath "$INSTDIR\subfolder"
File /r /x "*.xml" "C:\App\bin\subfolder\*.*"
SetOutPath "$INSTDIR"

I think the problem is that you shouldn't be specifying the full path to the files to exclude just a pattern, so in other words the command should look like this:
File /r /x data\someFile.xml /x data\derbydb\runtime\*.* ${InputDir}\*.*

The /x is for excluding some files to be included in the installer at compile time.
If I understand correctly, you want to avoid the overwriting of files during the installation / upgrade at run time.
Thus you could use the SetOverwrite compiler flag before the File directive. Look at the manual section 4.8.2.8 SetOverwrite, the section 4.8.2 also shows a method to handle SetOverwrite dynamically.

var pname
!define pname "Salt v1.2.9.3c"
File /r /x small-games.info.url "E:\Games\${pname}\*.*"
include E:\Games\${pname}*.*, but exclude small-games.info.url in folders

It seems to me there's a bug which is that if you do:
File /r "C:\folder a\subfolder b"
File /r /x "subfolder b" "C:\folder b"
then C:\folder b\subfolder a\subfolder b will still get copied as part of the first operation.

working example for files = File /r /x *.jpg D:\Desktop\NSIS\Examples\wp_test_build*.
working example for folders = File /r /x Config D:\Desktop\NSIS\Examples\wp_test_build*.*

Related

WinSCP script to synchronize directories, but exclude several subdirectories

I need to write a script that synchronizes local files with a remote machine.
My file structure is:
ProjectFolder/
.git/
input/
output/
classes/
main.py
readme.md
I need to synchronize everything, but:
completely ignore .git folder
ignore files in input and output folders, but copy the folder
So far my code is:
open sftp://me:password#server -hostkey="XXXXXXXX"
option batch abort
option confirm off
synchronize remote "C:\Users\MYNAME\Documents\MY FOLDER\Python Projects\ProjectFolder" "/home/MYNAME/py_proj/ProjectFolder" -filemask="|C:\Users\MYNAME\Documents\MY FOLDER\Python Projects\ProjectFolder\.git"
close
exit
First question: it doesn't seems to work.
Second question, how to add mask for input and output folder if I have spaces in file paths?
Thanks to all in advance.
Masks for directories have to end with a slash.
To exclude files in a specific folder, use something like */folder/*
-filemask="|.git\;*/input/*;*/output/*"

nsis adds empty folders to the installer

The File below:
; Install common files
SetOutPath "${GameDir}\Mopy"
File /r /x "*.bat" /x "*.py*" /x "w9xpopen.exe" /x "Wrye Bash.exe" "Mopy\*.*"
filters out some directories that contain python files but still those directories are created (although empty, or containing empty subdirectories) when I run the installer. Those folders need to be included to the installer (if I get the terminology correct at "compile time") cause the installer has an option to install the python version of the program. I can't come up with a way to not add these empty folders. Is there some wildcard I could use to that purpose or should I go and remove the files on installation (using RMDir ?) ?
I'd say you have two options and one is indeed RMDir if you are OK with it possibly removing empty folders that the user created.
The other option is to not use File /r ... and instead use !system to execute something like a batch file that generates a text file with individual File instructions that you can !include. It would look something like this:
!tempfile files
!system '"mygeneratefilelist.bat" "${files}"'
!include "${files}"
!delfile "${files}"
and the batch file would use FOR and/or DIR to list and ECHO the File commands to %1...

How to preserve file permissions with cmake "install directory" directive?

Prolog: I'm an idiot for missing this in the documentation
cmake-2.8.10.2
How do you make cmake preserve the original file permissions when installing a directory? For the project at hand, I'd like it to essentially copy some directories from my source tree to the install tree. To wit:
install(
DIRECTORY config runp
DESTINATION ${CMAKE_INSTALL_PREFIX}
PATTERN ".svn" EXCLUDE
PATTERN ".git" EXCLUDE
PATTERN "start_collection.snl" EXCLUDE
)
All works as expected -- except that executable scripts are getting copied in with incorrect file permissions. In fact, none of the original file permissions are preserved. Globally setting permissions using FILE_PERMISSIONS and DIRECTORY_PERMISSIONS is something I do not want to do, and frankly, would be a hack in this context.
In the shell-scripting world, I'd do something simple like this:
for i in config runp ; do
tar cf - $i | tar -C $CMAKE_INSTALL_PREFIX -xf -
done
Documentation suggests using USE_SOURCE_PERMISSIONS when calling install():
install(
DIRECTORY config runp
DESTINATION ${CMAKE_INSTALL_PREFIX}
USE_SOURCE_PERMISSIONS
PATTERN ".svn" EXCLUDE
PATTERN ".git" EXCLUDE
PATTERN "start_collection.snl" EXCLUDE
)
Alternatively, you can use install(PROGRAMS signature of this command. See docs for more info.

Recursively copy files that match a wildcard combination but not create the directory tree in DOS

I found that I can use xcopy /s to copy all files that match a wildcard combination in a folder to another location. But this command re-creates the folder structure. I do not want the tree. I need just the files dumped into the destination folder. There are no duplicate files in the source folder.
You can use for command:
for /R %%x in (*.cpp) do copy "%%x" "c:\dest\"
If you want to run it directly from command prompt (not from a batch file) use %x instead of %%x.
For your purpose, instead of using xcopy you should use robocopy:
http://en.wikipedia.org/wiki/Robocopy
http://technet.microsoft.com/en-us/library/cc733145(WS.10).aspx

Nsis - changing installation directory

Currently I am in my installing directory say c:\Program File\My installer.I have to execute a demo.bat file that is stored at some other location say c:\Program Files\Temp\example.bat,which I have to go at that location and execute coz my example.bat has some support files that are only stored in Temp folder.
My question is how can I change my installing directory to some other directory, execute demo.bat file and come back to my original installing directory while writing an nsis script?
When talking about "installing directory", I assume you mean current/working directory in the context of a batch file.
push $outdir ;save original path
SetOutpath "$programfiles\temp" ;set currect directory
nsExec::Exec "example.bat"
pop $outdir
SetOutpath $outdir ;restore
There are several ways to execute a batch file (Expand %comspec% and pass it to Exec/ExecWait, or use one of the exec plugins (nsExec,ExecDos,ExecCmd))

Resources