Archive: Archiving $INSTDIR using rename


Archiving $INSTDIR using rename
4.9.1.6 Rename
[/REBOOTOK] source_file dest_file
Rename source_file to dest_file. You can use it to move a file from anywhere on the system to anywhere else and you can move a directory to somewhere else on the same drive. The destination file must not exist or the move will fail (unless you are using /REBOOTOK). If /REBOOTOK is specified, and the file cannot be moved (if, for example, the destination exists), then the file is moved when the system reboots. If the file will be moved on a reboot, the reboot flag will be set. The error flag is set if the file cannot be renamed (and /REBOOTOK is not used) or if the source file does not exist.

Ok, I am trying to understand what this means. Firstly, do I need /REBOOTOK or not? I understand the purpose of the flag, but the name of the flag, and the text in the help is a bit confusing to me.

I have seen several other posts in regard to renaming a directory, but I can't for the life of me figure out why I am having trouble renaming files or directories. I just want to move the whole directory prior to putting files there.

So, I have logging as well, so I turn logging on in my $INSTDIR, then when I get to the archive part, I turn logging off, attempt to move the log into $TEMP, then move the entire $INSTDIR to an archive directory. It took me a while to figure out what the "error flag" is, BTW. It is all over the documentation, and usually it isn't shown in the examples. It would be nice to add a link to the IfErrors section (I know, a ton of busy work), for those of us who don't have time to read the entire manual cover to cover.

When you rename a directory, should the destination be there, or not? I am guessing not, but no matter what I try to do, it fails.

I am guessing I am being screwed by the logger, as it fails to rename the install.log file to the $TEMP directory successfully.

Any help would be welcome.

Thanks,

-Kevin

SetOutPath "$INSTDIR\.."

IfFileExists "$INSTDIR\${mcexec}" "" skipArchive
DetailPrint "Archiving old files"
;GetRoot "$INSTDIR" $R0
StrCpy $ArchivePath "$ArchiveRoot\${packagename}_Archive_$2$1$0_$4$5"
MessageBox MB_OK "Archive path is $ArchivePath"
;CreateDirectory "c:\$archive_$2$1$0_$4$5"
;Note that when using rename, the new path must not exist...
;but we need to create the root if it is missing...
CreateDirectory "$ArchiveRoot"
;CreateDirectory "$ArchivePath"
DetailPrint "About to move $INSTDIR to $ArchivePath"
DetailPrint "About to move $INSTDIR\install.log to $TEMP\install.log"
;turn logger off and move the log file to the side...
!insertmacro Logger off
ClearErrors
LogSet off
IfErrors 0 +2
MessageBox MB_OK "Turning the log off failed";
MessageBox MB_OK "Just turned off the logger";
ClearErrors
Rename "$INSTDIR\install.log" "$TEMP\install.log"
IfErrors 0 +2
MessageBox MB_OK "Rename $INSTDIR\install.log to $TEMP\install.log failed";

;CopyFiles "$INSTDIR\*.*" "$ArchivePath"
ClearErrors
Rename "$INSTDIR" "$ArchivePath"
IfErrors 0 +2
MessageBox MB_OK "Rename $INSTDIR to $ArchivePath failed";
;put logfile back and turn logger back on
MessageBox MB_OK "Rename complete ($0), about to copy the log back";
ClearErrors
Rename "$TEMP\install.log" "$INSTDIR\install.log"
IfErrors 0 +2
MessageBox MB_OK "Rename $TEMP\install.log to $INSTDIR\install.log failed";
!insertmacro Logger on
MessageBox MB_OK "Just turned on the logger (the log rename returned $0)";
DetailPrint "Archive complete"
skipArchive:


OK, I was correct. I am screwed by the logger. LogSet off does not close the file, so when you try to rename it, you get:
The process cannot access the file because it is being used by another process.

I am not sure if this is the only bug here, but I will hopefully find out shortly.

BTW, is there a mechanism to actually get the error message for why something failed? I am guessing if there was a way, it would be shown in the IfErrors section of the help manual.


Use /REBOOTOK to rename the file on reboot, or try CopyFiles followed by Delete /REBOOTOK. You do realise that if an error occurs you will get both messages boxes - one saying something was successful and one saying it was not. You need to jump over your second message box (easiest way is to add IDOK +2 onto the end of the first MessageBox.)
Also those ; on the end of the MessageBox calls are not necessary and anything after them will be denoted as a comment.

Stu


Yeah, I know -- they were just a bunch of debug I threw in there. I missed the ; on the end -- C++ programmer by trade, I just did it out of habit.

BTW, there is something up that seems to hang on the directory and keep it from being deleted. I just blew about 4 hours on this because Rename doesn't support wild cards, the logger bug, and what I just mentioned about something hanging onto the directory until you reboot.

Anyway, Rename does not work reliably. I am not sure if it is NSIS or the WinZip self extractor, but one of the two is screwing me now. I will take your suggestion about CopyFiles, then Delete. I really hate to take that action, because rename is an instant change, and copying takes 10-15 minutes and then deleting takes a bunch of time too. Argh.

Thanks for the help understanding what a /REBOOTOK flag should do.


Well, here is what I came up with as an alternative. We will see how well it works out. This is the last-ditch effort before I go and copy/delete everything.

archiveFiles:
;CopyFiles "$INSTDIR\*.*" "$ArchivePath"
ClearErrors
Rename "$INSTDIR" "$ArchivePath"
IfErrors 0 +2
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "Rename $INSTDIR to $ArchivePath failed" IDCANCEL skipArchive IDRETRY archiveFiles
;put logfile back and turn logger back on
DetailPrint "Archive complete"
skipArchive:
;it sucks to have to do this here, but the logger doesn't close the file when commanded off
!insertmacro Logger on

Thanks again for the help!