Archive: Uninstall Log for File /r

Uninstall Log for File /r
I'm trying to create a uninstall log that records every file that is installed so that my uninstaller only removes the files that were originally installed. I haven't made a whole lot of progress though because I'm finding it difficult to log File /r commands.

Here is my current progress, please be aware that this script does NOT work, but it is my current progress.

Var UninstallLog
!macro InstallDirectory Directory
File /r "${Directory}"
Push "${Directory}"
Call InstallDirectoryFiles

Function InstallDirectoryFiles
Pop $3
FindFirst $0 $1 "$INSTDIR\$3\*"
FindNext $0 $1
FindNext $0 $1
StrCpy $2 "$3\$1"
Goto Loop
DetailPrint "First 1: $1"
StrCmp $1 "" NextMain
StrCmp $1 "." Next
StrCmp $1 ".." Next
DetailPrint "Second 2: $2"
IfFileExists "$2\*" IsDir IsFile
FindFirst $0 $1 "$INSTDIR\$2\*"
StrCmp $1 "" Close
StrCmp $1 "." NextDir
StrCmp $1 ".." NextDir
FileOpen $UninstallLog "$INSTDIR\uninstall.log" a
FileSeek $UninstallLog 0 END
FileWrite $UninstallLog "$2\$1$\r$\n"
FileClose $UninstallLog
StrCpy $2 "$2\$1"
DetailPrint "Third 2: $2"
Goto Next
FileOpen $UninstallLog "$INSTDIR\uninstall.log" a
FileSeek $UninstallLog 0 END
FileWrite $UninstallLog "$2\$1$\r$\n"
FileClose $UninstallLog
DetailPrint "Forth 2: $2"
Goto Next
FindNext $0 $1
Goto IsDir
FindNext $0 $1
Goto Loop
FindClose $0
FindNext $0 $1
Call InstallDirectoryFiles
FindClose $0

And this is called by:

!insertmacro InstallDirectory "lib"

I need to log File /r because I have many subfolders and a lot of files.

Please let me know if there is an easier way, or where I'm going wrong with my current script.

This will only work in $INSTDIR is empty when install begins, and stuff is only installed in $INSTDIR.

A better way would be to create something that logs compression at compiletime. Could be done using !execute and an (nsis) exe that writes an nsh with all the files to be compressed on the compilation machine.

Do you have an example of the type of log system you talked about?

I'm still fairly new with NSIS.

No, but my point is that you probably want to make the log at compiletime. Since the amount of compiletime commands is very limited in the current version of NSIS (v3 will be better), you'll need to use !execute to launch another exe during compilation, which will generate your list for you. So you'd need to make an (NSIS) exe that generates an nsh file that contains
file "Relative path\filename"
file "Relative path\filename2"
for each file found in the relative path that you'd normally use File /r on.
And it would also write an nsh file containing
"Delete $INSTDIR\Filename"
for each. Although I'm not yet sure how you can make this work for other paths, too... It's undoubtedly possilble, but it would take some smart coding.

So I need to code a NSIS nsi script that generates the directory structure, compile that, and use the compiled exe in the actual installer to generate a the list?

That first NSIS exe should write the directory structure to a .nsh file so that it can be easily loaded by the installer?

I'm just trying to confirm if I understand this right.

That is really the best way to make an uninstall log? Would you recommend anything else? That seems like a lot of work, and it would seem to me like I'm just doing the same sort of scripting, just calling it externally.

No, the nsh file wouldn't be loaded by the installer, it would loaded by the compiler using !include. That way the list gets created at compiletime, instead of at runtime.

So do I write the nsh file myself, or does something else create it?

To go through this much work, am I doing something wrong?

1) Create an (NSIS) exe that uses FindFirst/FindNext or Locate plugin or whatever, to generate a filename list. Make it save this list to Files.nsh, with each line saying File "Path\to\filename.ext". Also make it save this list to UnFiles.nsh, with each line saying Delete "$INSTDIR\path\to\filename.ext".
2) In your actual script, at the top do !execute YourExe.exe. At the point where you currently do File /r, put !include Files.nsh . In the uninstaller section, do !include UnFiles.nsh .

But it was just an idea. If you think it's too much work, you're free to use your own solution. Wasn't there some logging header file with logging functions that support /r, somewhere on the wiki?

This shows an example of executing a script at compile time: