Read numbers in the name of a file by NSIS - nsis

I have to extract a file to an output folder in my NSIS installer. The name of the file contains its version number. I need a method to read the number written in the name of my file.
Example File name:
MyFile_4.3_runtime_80968_x64.exe
I used the following code to read it automatically:
Var Version
Section
${GetFileVersion} "F:\FilesToBeInstalled\MyFile_4.3_runtime_?????_x64.exe" $Version
MessageBox MB_OK "Version: $Version"
SectionEnd
earlier it used to work for me. But suddenly it has stopped working. If I write the proper number instead of writing ????? then it works. For example, the following code works for me:
Var Version
Section
${GetFileVersion} "F:\FilesToBeInstalled\MyFile_4.3_runtime_80698_x64.exe" $Version
MessageBox MB_OK "Version: $Version"
SectionEnd

GetFileVersion reads the version-information of the file, it does not parse the file-name. It has likely been a coincidence that it worked before.
You can use WordFind2x to search between two delimiters:
!include "WordFunc.nsh"
Var Version
Var File
Section
# find instances of MyFile_4.3_runtime*
FindFirst $0 $File "F:\FilesToBeInstalled\MyFile_4.3_runtime*.exe"
loop:
StrCmp $File "" done
# parse hit for version string
${WordFind2X} $File "MyFile_4.3_runtime_" ".exe" "-1" $Version
DetailPrint "$File contains version $Version"
FindNext $0 $File
Goto loop
done:
FindClose $0
SectionEnd

Related

NSIS DELETE all files by extension

I'm trying to delete all files with a specific extension in a folder. I found this question on how to get all txt files and I thought about using that to get all files by extension and removing them, but I'm not sure how to do that.
There is no difference between listing and deleting files:
FindFirst $0 $1 "$INSTDIR\*.txt"
loop:
StrCmp $1 "" done
StrCpy $2 "$INSTDIR\$1"
IfFileExists "$2\*.*" +2 ; A directory?
Delete "$2"
FindNext $0 $1
Goto loop
done:
FindClose $0
That being said, the documentation says wildcards are supported so you should be able to just do
Delete "$INSTDIR\*.txt"

NSIS - how to stop it from creating a directory?

Upon uninstalling, I go through a list of installed subdirectories (List - C#)and delete them. I check if a directory exists and if so, I want to remove it. Here's the code:
//here it deletes the testfolder1 directory - perfect
${If} ${FileExists} "$MUSIC\testFolder1\*"
RMDir "$MUSIC\testFolder1"
${EndIf}
//problem - here, instead of ONLY CHECKING if directory exists,
// it creates "testFolder1" again!
${If} ${FileExists} "$MUSIC\testFolder1\testfolder2\*"
RMDir "$MUSIC\testFolder1\testfolder2"
${EndIf}
I know I could swap the two ifs and it would work but it doesn't solve anything, because directories are in a random order in my list. Is there any way to stop NSIS from creating directories upon checking if they exist? I have looked for a solution online but found absolutely nothing.
I don't really see how that is possible, ${IfFileExists} is a wrapper around IfFileExists and internally this NSIS instruction is implemented with FindFirstFile. There is not way this is going to create a directory!
The upside is that you don't have to use ${IfFileExists} because RMDir (without /r) will only delete the directory if it is empty and does nothing if it does not exist.
If you don't know the order of the directories nor if they can be nested at compile-time then you must keep trying to delete as long as you succeeded to delete at least one item:
!include LogicLib.nsh
Section
CreateDirectory "$Temp\testFolder1"
CreateDirectory "$Temp\testFolder1\testfolder2"
!macro TryRMDir path counter
ClearErrors
${IfThen} ${FileExists} "${path}" ${|} IntOp ${counter} ${counter} + 1 ${|}
RMDir "${path}"
${IfThen} ${FileExists} "${path}" ${|} IntOp ${counter} ${counter} - 1 ${|}
!macroend
loop:
StrCpy $0 0
!insertmacro TryRMDir "$Temp\testFolder1" $0
!insertmacro TryRMDir "$Temp\testFolder1\testfolder2" $0
StrCmp $0 0 "" loop ; If we deleted anything we must try again
SectionEnd

How to know which uninstaller has been invoked if multiple uninstallers are present

I have a requirement to create two uninstallers with different names. Each will remove different folders. I am using the same project/script to create uninstallers. How can i find that which uninstaller has been invoked by the user? So that i can use that value in un.onInit and remove the corresponding folders?
Similarly if the same script is creating two installers, how to find which installer has been invoked by the user?
Installers:
Section
!ifdef INSTALLER_OTHER
DetailPrint "Other"
!else
DetailPrint "Normal"
!endif
SectionEnd
Generate the other installer with makensis.exe /DINSTALLER_OTHER setup.nsi
Uninstallers:
You could check the uninstaller filename:
!include FileFunc.nsh
!include LogicLib.nsh
Section un.Whatever
${GetExeName} $0
${GetBaseName} $0 $0 ; Remove path and extension
${If} $0 == "OtherUninst"
RMDir "Other"
${Else}
RMDir "Normal"
${EndIf}
SectionEnd
Or the installer can write a special file that you check for.
Or embed special data in the uninstaller:
InstallDir "$Temp\TestInst"
!include LogicLib.nsh
Section
SetOutPath $InstDir
WriteUninstaller "$InstDir\Uninst.exe"
FileOpen $0 "$InstDir\Uninst.exe" a
FileSeek $0 0 END
!ifdef INSTALLER_OTHER
FileWriteByte $0 1
!else
FileWriteByte $0 0
!endif
FileClose $0
SectionEnd
Section -Uninstall
FileOpen $0 "$EXEPATH" r
FileSeek $0 -1 END
FileReadByte $0 $1
FileClose $0
${If} $1 = 1
RMDir "Other"
${Else}
RMDir "Normal"
${EndIf}
SectionEnd
With the addition of Anders solutions, you could go for a registry write-read method. It will be a quick operation i.e. Whenever you run any uninstaller just write a registry value and set it's value. Afterwards you just need to read that registry values and process accordingly.

Remove "Installing" from NSIS installer window title

I have an NSIS installer script that I'm using to deploy a py2exe-built app (using NSIS 2.46). The only UI detail I can't iron out is the window title on the installer.
According to the docs, the Caption directive should set this text. But whatever I set, it always has the text ": Installing" appended to it. That is, if I have:
Caption "My Special App"
...then the window title on the installer shows "My Special App: Installing". How do I get around this?
(I want to avoid this because I'm actually using the NSIS installer to extract the app to a temporary directory and run it once, not to permanently install it.)
My entire NSI file is:
!define py2exeOutputDirectory 'C:\Path\To\P2EOutput'
!define exe 'MyApp.exe'
; Comment out the "SetCompress Off" line and uncomment
; the next line to enable compression. Startup times
; will be a little slower but the executable will be
; quite a bit smaller
;SetCompress Off
SetCompressor /SOLID lzma
Caption "My Special App"
Name 'MyApp'
OutFile ${exe}
Icon 'C:\Path\To\Icon\icon.ico'
;SilentInstall silent
AutoCloseWindow true
ShowInstDetails nevershow
Section
DetailPrint "Extracting program..."
SetDetailsPrint none
InitPluginsDir
SetOutPath '$PLUGINSDIR'
File /r '${py2exeOutputDirectory}\*'
GetTempFileName $0
;DetailPrint $0
Delete $0
StrCpy $0 '$0.bat'
FileOpen $1 $0 'w'
FileWrite $1 '#echo off$\r$\n'
StrCpy $2 $TEMP 2
FileWrite $1 '$2$\r$\n'
FileWrite $1 'cd $PLUGINSDIR$\r$\n'
FileWrite $1 '${exe}$\r$\n'
FileClose $1
HideWindow
nsExec::Exec $0
Delete $0
SectionEnd
SubCaption 3 " "
or
PageEx InstFiles
Caption " "
PageExEnd
or
LangString "^InstallingSubCaption" 0 " "

Mac osx terminal commands in an automation

I need to create an automation that takes files as inputs and uses their location string as an input variable to a script. I also need it ask for a string before running the script. How would I go about doing this?
The command line code I want to execute:
convert (file-location) -page '(string)' (file-location)
Thanks in advance!
How about this?
#!/bin/bash
if [ $# -ne 2 ]
then
echo "Usage: $0 <path_to_input_file>"
fi
echo "Processing $1. Enter string: "
read a
convert $1 -page "$a" $1
You invoke this script with one file name at a time, for that file it asks you for the string to be used. You could rewrite this to loop over a bunch of files too.

Resources