Archive: Help needed to compile helper!


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!

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:
http://nsis.sourceforge.net/RecFind:...t%2C_FindClose

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

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?


@ -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!

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

You don't need CreateDirectory because SetOutPath create it.


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


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

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

@ 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!


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: 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

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.