Skip to content
⌘ NSIS Forum Archive

Help needed to compile helper!

13 posts

Red Wine#edited

Help needed to compile helper!

well, based on Instructor's functions and code posted on other topics I'm trying to compile a script that takes a given directory and builds a proper list ready to !include in install section. This could be a helper to parse the entire directory structure in the installation script. The code that I'm figuring is this:
OutFile test.exe
Name "NSIS Script Helper"

!include "FileFunc.nsh"

!insertmacro Locate

!define DirName 'D:\New_Installation'
!define FileList '$EXEDIR\Files.lst'

var TargetDir

Section
FileOpen $R1 ${FileList} w
${Locate} "${DirName}" "/L=F /M=*.*" "LocateCallBack"
FileClose $R1
IfErrors 0 +2
MessageBox MB_OK "Error" IDOK +2
Exec '"notepad.exe" "${FileList}"'
SectionEnd

Function LocateCallBack
StrLen $R2 '${DirName}'
StrCpy $TargetDir $R8 '' $R2
StrCmp $TargetDir '' +1 +3
FileWrite $R1 'SetOutPath "$$INSTDIR"$\r$\n'
goto +2
FileWrite $R1 'CreateDirectory "$$INSTDIR$TargetDir"$\r$\nSetOutPath "$$INSTDIR$TargetDir"$\r$\n'
FileWrite $R1 'File "$R8\$R7"$\r$\n'
Push $0
FunctionEnd
The resulting list where I really stuck is this:
SetOutPath "$INSTDIR"
File "D:\New_Installation\root.dll"
SetOutPath "$INSTDIR"
File "D:\New_Installation\rootexec.exe"
CreateDirectory "$INSTDIR\subdir"
SetOutPath "$INSTDIR\subdir"
File "D:\New_Installation\subdir\other_recourse.dll"
CreateDirectory "$INSTDIR\subdir"
SetOutPath "$INSTDIR\subdir"
File "D:\New_Installation\subdir\recourse.dll"
CreateDirectory "$INSTDIR\subdir\Folder"
SetOutPath "$INSTDIR\subdir\Folder"
File "D:\New_Installation\subdir\Folder\somedll.dll"
CreateDirectory "$INSTDIR\subdir\Folder"
SetOutPath "$INSTDIR\subdir\Folder"
File "D:\New_Installation\subdir\Folder\some_other.dll"
CreateDirectory "$INSTDIR\documents"
SetOutPath "$INSTDIR\documents"
File "D:\New_Installation\documents\help.pdf"
CreateDirectory "$INSTDIR\documents"
SetOutPath "$INSTDIR\documents"
File "D:\New_Installation\documents\more_help.html"
I can't handle how I should write the code to eliminate the repeated lines 'SetOutPath...' and 'CreateDirectory...' so the resulting list will be like this:
SetOutPath "$INSTDIR"
File "D:\New_Installation\root.dll"
File "D:\New_Installation\rootexec.exe"

CreateDirectory "$INSTDIR\subdir"
SetOutPath "$INSTDIR\subdir"
File "D:\New_Installation\subdir\other_recourse.dll"
File "D:\New_Installation\subdir\recourse.dll"

CreateDirectory "$INSTDIR\subdir\Folder"
SetOutPath "$INSTDIR\subdir\Folder"
File "D:\New_Installation\subdir\Folder\somedll.dll"
File "D:\New_Installation\subdir\Folder\some_other.dll"

CreateDirectory "$INSTDIR\documents"
SetOutPath "$INSTDIR\documents"
File "D:\New_Installation\documents\help.pdf"
File "D:\New_Installation\documents\more_help.html"
Help please!
Afrow UK#
I'm not sure why CreateDirectory is being used in the first place. With the above code you'll find that all the files will get dumped in $INSTDIR (because SetOutPath sets the output directory, and it's being set to $INSTDIR to begin with and it's never being changed thereafter).

You could try the RecFind script header at:


Your code would then look like this:

OutFile GenerateFileList.exe
Name "GenerateFileList"

!include RecFind.nsh

!define DirName 'D:\New_Installation'
!define FileList '$EXEDIR\Files.lst'

Section
FileOpen $R2 ${FileList} w

${RecFindOpen} "${DirName}" $R0 $R1
FileWrite $R2 'SetOutPath "$\r$\n${DirName}$R0$\r$\n"'
${RecFindFirst}
FileWrite $R2 'File "${DirName}$R0\$R1$\r$\n"'
${RecFindNext}
${RecFindClose}

FileClose $R2
Quit
SectionEnd
Although the code is much simpler you have less options here. I actually implemented a file extension filter into ${RecFindFirst} but for some reason I never uploaded the changes and now I've lost them altogether. I'll probably sort this out sometime.

-Stu
Red Wine#
oops sorry!
I missed a line in my code! now it's fixed and writes the proper SetOutPath for every created directory. Yet, the problem is still there! how can I eliminate the repeated lines?
Red Wine#
@ -Stu
This is the list I got with your function.
SetOutPath "
D:\New_Installation
"File "D:\New_Installation\root.dll
"File "D:\New_Installation\rootexec.exe
"SetOutPath "
D:\New_Installation\subdir
"File "D:\New_Installation\subdir\other_recourse.dll
"File "D:\New_Installation\subdir\recourse.dll
"SetOutPath "
D:\New_Installation\subdir\Folder
"File "D:\New_Installation\subdir\Folder\somedll.dll
"File "D:\New_Installation\subdir\Folder\some_other.dll
"SetOutPath "
D:\New_Installation\documents
"File "D:\New_Installation\documents\help.pdf
"File "D:\New_Installation\documents\more_help.html
"
Quite close to what I'm looking for!!!
I should change the variables when writing to the file to point the InstallDir and subdirs and create them also. That's OK I guess, I'm going to make it later. Yet, there are some strange things with the quotes. How should I fix them?
Thanks anyway!
Red Wine#
The quotes was the easiest thing!
Based on Stu's code above here is the script:
OutFile GenerateFileList.exe
Name "GenerateFileList"

!include RecFind.nsh

!define DirName 'D:\New_Installation'
!define FileList '$EXEDIR\Files.lst'

Section
FileOpen $R2 ${FileList} w

${RecFindOpen} "${DirName}" $R0 $R1
StrCmp '$R0' '' +1 +3
FileWrite $R2 'SetOutPath "$$INSTDIR$R0"$\r$\n'
Goto +2
FileWrite $R2 'CreateDirectory "$$INSTDIR$R0"$\r$\nSetOutPath "$$INSTDIR$R0"$\r$\n'
${RecFindFirst}
FileWrite $R2 'File "${DirName}$R0\$R1"$\r$\n'
${RecFindNext}
${RecFindClose}

FileClose $R2
Quit
SectionEnd
And here is the resulting list:
SetOutPath "$INSTDIR"
File "D:\New_Installation\root.dll"
File "D:\New_Installation\rootexec.exe"
CreateDirectory "$INSTDIR\subdir"
SetOutPath "$INSTDIR\subdir"
File "D:\New_Installation\subdir\other_recourse.dll"
File "D:\New_Installation\subdir\recourse.dll"
CreateDirectory "$INSTDIR\subdir\Folder"
SetOutPath "$INSTDIR\subdir\Folder"
File "D:\New_Installation\subdir\Folder\somedll.dll"
File "D:\New_Installation\subdir\Folder\some_other.dll"
CreateDirectory "$INSTDIR\documents"
SetOutPath "$INSTDIR\documents"
File "D:\New_Installation\documents\help.pdf"
File "D:\New_Installation\documents\more_help.html"
Thanks Stu
Red Wine#
Hi Instructor,
need it or not, do you have any suggestions how to eliminate the repeated lines for the example (top of the page} based in your code?
Thanks in advance
Afrow UK#
No need for this at all in the RecFind script:
   StrCmp '$R0' '' +1 +3
FileWrite $R2 'SetOutPath "$$INSTDIR$R0"$\r$\n'
Goto +2
FileWrite $R2 'CreateDirectory "$$INSTDIR$R0"$\r$\nSetOutPath "$$INSTDIR$R0"$\r$\n'
Anything between ${RecFindOpen} and ${RecFindFirst} is executed only when moving into a new directory and not for each new file found. Also $R0 (the directory path) will never be empty "" so it will always jump to the second FileWrite instruction anyway.

Therefore you just need:

FileWrite $R2 'SetOutPath "$$INSTDIR$R0"$\r$\n'
SetOutPath creates the directories recursively as well! So no need for CreateDirectory.

-Stu
Instructor#
do you have any suggestions how to eliminate the repeated lines for the example (top of the page} based in your code?
Name "Output"
OutFile "Output.exe"

!include "FileFunc.nsh"
!insertmacro Locate

!define DirName 'C:\TC'
!define FileList '$EXEDIR\Files.lst'

Section
StrCpy $R0 ''
StrLen $R1 '${DirName}'
FileOpen $R3 '${FileList}' w
FileWrite $R3 'SetOutPath "$$INSTDIR"$\r$\n'
${Locate} "${DirName}" "/L=F /M=*.*" "LocateCallBack"
FileClose $R3

IfErrors 0 +2
MessageBox MB_OK "Error" IDOK +2
Exec '"notepad.exe" "${FileList}"'
SectionEnd

Function LocateCallBack
StrCpy $1 $R8 '' $R1
StrCmp $R0 $1 +4
StrCpy $R0 $1
FileWrite $R3 'SetOutPath "$$INSTDIR$R0"$\r$\n'
goto +2
FileWrite $R3 'File "$R9"$\r$\n'

Push $0
FunctionEnd
Red Wine#
@ Stu:
Yes, you're always turning on the light! I used SetOutPath $INSTDIR in my install section also, that's why appeared two times up there!
@ Instructor:
I'll check that later, yet, I'm sure it works.

Thanks, I'm learning from you people, and I like it!
Red Wine#
OK, no need for CreateDirectory while SetOutPath creates the directories recursively as mentionend above. I use it just to have the list in tact.
@ Instructor: The code in your last post getting closer. There are not repeated lines, though, it takes only the first file found into every subdir.
Instructor#
@ Instructor: The code in your last post getting closer. There are not repeated lines, though, it takes only the first file found into every subdir.
Oops 🙂
Name "Output"
OutFile "Output.exe"

!include "FileFunc.nsh"
!insertmacro Locate

!define DirName 'C:\TC'
!define FileList '$EXEDIR\Files.lst'

Section
StrCpy $R0 ''
StrLen $R1 '${DirName}'
FileOpen $R3 '${FileList}' w
FileWrite $R3 'SetOutPath "$$INSTDIR"$\r$\n'
${Locate} "${DirName}" "/L=F /M=*.*" "LocateCallBack"
FileClose $R3

IfErrors 0 +2
MessageBox MB_OK "Error" IDOK +2
Exec '"notepad.exe" "${FileList}"'
SectionEnd

Function LocateCallBack
StrCpy $1 $R8 '' $R1
StrCmp $R0 $1 +3
StrCpy $R0 $1
FileWrite $R3 'SetOutPath "$$INSTDIR$R0"$\r$\n'
FileWrite $R3 'File "$R9"$\r$\n'

Push $0
FunctionEnd
Red Wine#
COOL! Both working perfect!
Such things I could not manage by my self yet.
Keep going. Scratching NSIS's shell. With these two tools, let's see If I can figure a simple helper gui which offers options to select a given dir and all subdirs, select only files into the root of the given dir, or select individual files from different locations and build a list ready to !include. Besides the scratching, I guess would be usefull if one could save some typing while building an installation.
I'll come back later.