Old 12th January 2014, 22:39   #1
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
Back up and restore files

Let me preface this post the same as my other. I apologize for my ignorance. I've already spent a few days researching and attempting rectify my issue, without success.

I'm attempting to make my installer backup the present file and then restore it upon uninstall, but I cannot get this to work correctly. I'm modeling my script using a sample script from another installer that I know works (I've used the installer).

I know the problem has something to do with how I've set up the directories. I know that because I can get both the backup/rename/uninstall features to work if I don't use a relative path, and instead simply point to a specific directory (in my case, H:\ME3_dummy).

Here are some snippets of the sample code I'm working off :

Quote:
InstallDir "$PROGRAMFILES"
InstallDirRegKey HKLM "Software\BioWare\Mass Effect 3" "Install Dir"

DetailPrint "copying remaining files..."
SetOverwrite on
SetOutPath "$INSTDIR\BIOGame"

IfFileExists "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup" +2 0
Rename "$INSTDIR\BIOGame\PCConsoleTOC.bin" "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup"
File "BIOGame\PCConsoleTOC.bin"
Uninstall looks like this (the program previous used .bak files, but now uses .bup files):

Quote:
IfFileExists "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup" 0 +4
Delete "$INSTDIR\BIOGame\PCConsoleTOC.bin"
Rename "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup" "$INSTDIR\BIOGame\PCConsoleTOC.bin"
Goto +4
IfFileExists "$INSTDIR\BIOGame\PCConsoleTOC.bin.bak" 0 +3
Delete "$INSTDIR\BIOGame\PCConsoleTOC.bin"
Rename "$INSTDIR\BIOGame\PCConsoleTOC.bin.bak" "$INSTDIR\BIOGame\PCConsoleTOC.bin"
And, here's a sample of what mine looks like. In my case, the new files are copied over, but backups are not made.

Quote:
InstallDir "$PROGRAMFILES"
InstallDirRegKey HKLM "Software\BioWare\Mass Effect 3" "Install Dir"

Section "Expanded Core Module for EC" SEC01
SectionIn RO
SetOutPath "$INSTDIR\BIOGame\CookedPCConsole"
SetOverwrite on

IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" +2 0
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2"
File "Conditionals.cnd"
And, here's a portion of my uninstall. When it comes time to uninstall, there are not any .bu2 files created, so it makes sense the new files wouldn't get uninstalled. However, the files that are simply copied/created without backups being made, also aren't being uninstalled.

Quote:
Section Uninstall
IfFileExists "$INSTDIR\BIOGame\UNINSTALL_ThaneMOD_v1B.exe" 0 +2
Delete "$INSTDIR\BIOGame\UNINSTALL_ThaneMOD_v1B.exe"

IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\BioD_CitHub_HospitalP2_LOC_INT.pcc.bu2" 0 +2
Delete "$INSTDIR\BIOGame\CookedPCConsole\BioD_CitHub_HospitalP2_LOC_INT.pcc"
Rename "$INSTDIR\BIOGame\CookedPCConsole\BioD_CitHub_HospitalP2_LOC_INT.pcc.bu2" "$INSTDIR\BIOGame\CookedPCConsole\BioD_CitHub_HospitalP2_LOC_INT.pcc"
If anyone is willing to take the time to help, I'd very much appreciate it.

If it is helpful, here's a pastebin of the full installer: http://pastebin.com/jy7ppHeU

Thanks much.
moho9 is offline   Reply With Quote
Old 13th January 2014, 08:26   #2
JasonFriday13
Major Dude
 
JasonFriday13's Avatar
 
Join Date: May 2005
Location: New Zealand
Posts: 923
You're close, the problem is that in the sample code, it's checking for the backup file, while in yours it's checking for the main file (the relative vs absolute thing is not the problem).
Quote:
Originally Posted by Sample code
IfFileExists "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup" +2 0
Rename "$INSTDIR\BIOGame\PCConsoleTOC.bin" "$INSTDIR\BIOGame\PCConsoleTOC.bin.bup"
File "BIOGame\PCConsoleTOC.bin"
And this basically says that if the file exists, skip it (it's checking the main file, not the backup):
Quote:
Originally Posted by Your code
IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" +2 0
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2"
File "Conditionals.cnd"
It should look like this (this mirrors the sample code):
Quote:
IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2" +2 0
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2"
File "Conditionals.cnd"
Or you can change the logic so that the file is renamed if it exists:
Quote:
IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" 0 +2
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2"
File "Conditionals.cnd"
Looks like the uninstall code is ok, I haven't looked at the full installer code though. Logic errors can be a pain to track down, hope this helps.

"Only a MouseHelmet will save you from a MouseTrap" -Jason Ross (Me)
NSIS 3 POSIX Ninja
Wiki Profile
JasonFriday13 is offline   Reply With Quote
Old 13th January 2014, 16:38   #3
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
@JasonFriday13 --

Thank you so very much for your help!

That swap of the 0 +2 to +2 0 for the backup got it working. So, now a snippet of the install section looks like this:

Quote:
Section "Core Module for EC" SEC01
SectionIn RO
SetOutPath "$INSTDIR\BIOGame\CookedPCConsole"
SetOverwrite on

IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" 0 +2
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2"
File "Conditionals.cnd"
It renames the original file to the ".bu2" extension and copies over the new file, just as intended. The uninstall is still failing though -- it "completes successfully", but none of the files are removed or renamed as they should. Nothing happens short of the message box popping up. What should be happening is the new file gets deleted and the original, backed up file with the .bu2 extension should have that extension dropped (restoring the original name).

Similar uninstall code for the above file looks like:

Quote:
Section Uninstall
IfFileExists "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2" 0 +2
Delete "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd"
Rename "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd.bu2" "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd"
I tried reversing the 0 +2, but that didn't work, either. Obviously I am still missing something. Any other ideas?
moho9 is offline   Reply With Quote
Old 13th January 2014, 21:47   #4
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Instead of using relative jumps (such as +2 which can be confusing) I would use LogicLib instead.
code:
${If} ${FileExists} `path`
[do this]
${EndIf}

If it still does not work then check your paths (file names) are correct.

Stu
Afrow UK is offline   Reply With Quote
Old 13th January 2014, 22:24   #5
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
Thanks for the input, Stu.

I'm still not having any luck, unfortunately. I've been messing with it all day. The file paths themselves are correct, the only issue I could be maybe something with the relative path? But, this also seems ok to me.

If you are willing to take a look, I've put up the entire installer script on a pastebin. Everything works except for the uninstall. I don't get any compiling errors, but it still does the same thing upon uninstallation -- the new files stick around and the old ones don't get renamed. You'll see files with your scheme and others using the other scheme. Nothing is uninstalled, regardless of what scheme is used.

http://pastebin.com/uv9iJKSc
moho9 is offline   Reply With Quote
Old 13th January 2014, 23:58   #6
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
Yeah, it's something with the relative path of the Install Directory. Well, that's what I thought with the install and backing up, also, but it wasn't that.

The only way I can get the uninstall to work correctly, though, is if I define an exact file path. For example:

"C:\Program Files (x86)\Origin Games\Mass Effect 3\BIOGame\CookedPCConsole\File_01.txt"

Quote:
${If} ${FileExists} "C:\Program Files (x86)\Origin Games\Mass Effect 3\BIOGame\CookedPCConsole\File_01.txt"
Rename "C:\Program Files (x86)\Origin Games\Mass Effect 3\BIOGame\CookedPCConsole\File_01.txt" "C:\Program Files (x86)\Origin Games\Mass Effect 3\BIOGame\CookedPCConsole\File_01.txt.bu2"
File "C:\Users\User\Desktop\File_01.txt"
${EndIf}
But, not everyone will have the program installed in this location. So, instead I use:

"$INSTDIR\BIOGame\CookedPCConsole\File_01.txt"

But if I use this in the uninstall section it doesn't work. Yet it works in the install section.

How can that be?
moho9 is offline   Reply With Quote
Old 14th January 2014, 09:42   #7
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
FYI
Quote:
Note that in uninstaller code, $INSTDIR contains the directory where the uninstaller lies. It does not necessarily contain the same value it contained in the installer. For example, if you write the uninstaller to $WINDIR and the user doesn't move it, $INSTDIR will be $WINDIR in the uninstaller. If you write the uninstaller to another location, you should keep the installer's $INSTDIR in the registry or an alternative storing facility and read it in the uninstaller.
Stu
Afrow UK is offline   Reply With Quote
Old 15th January 2014, 00:02   #8
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
@Stu -- I read that snippet in the documentation, but as far as I can tell, the installer is already doing that in this part:

Quote:
Section -Post
WriteUninstaller "$INSTDIR\BIOGame\UNINSTALL_ThaneMOD_v1A.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\BIOGame\UNINSTALL_ThaneMOD_v1A.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
SectionEnd
And, isn't the uninstaller supposed to be reading this information by default when the user launches it?

The only other thing I can think of is maybe this line in the installer is the problem?

Quote:
InstallDirRegKey HKLM "Software\BioWare\Mass Effect 3" "Install Dir"
I took this line from another installer's script. My understanding was it was supposed to help detect the default install location of the game. Note, that the $INSTDIR for the installer is:

Quote:
InstallDir "$PROGRAMFILES\Origin Games\Mass Effect 3"
moho9 is offline   Reply With Quote
Old 15th January 2014, 03:12   #9
JasonFriday13
Major Dude
 
JasonFriday13's Avatar
 
Join Date: May 2005
Location: New Zealand
Posts: 923
Try putting this in your uninstall section to see what it says:
DetailPrint "$INSTDIR\BIOGame\CookedPCConsole\Conditionals.cnd"

From what Afrow UK said, if you write your uninstaller to "$INSTDIR\BIOGame\uninstall.exe", then in the uninstaller $INSTDIR will be "C:\Program Files (x86)\Origin Games\Mass Effect 3\BIOGame". Your uninstaller will work properly if it's written to $INSTDIR, ie: WriteUninstaller "$INSTDIR\uninstall.exe", but the uninstaller filename should be more descriptive than that.

"Only a MouseHelmet will save you from a MouseTrap" -Jason Ross (Me)
NSIS 3 POSIX Ninja
Wiki Profile
JasonFriday13 is offline   Reply With Quote
Old 15th January 2014, 22:40   #10
moho9
Junior Member
 
Join Date: Jan 2014
Posts: 9
Well, I found a solution, though I'm not sure it's what either of you were saying.

Taking a closer look at the simplest default installer/uninstaller I could make with HM NIS Edit, I figured out that if I simply left the uninstaller .exe in the $INSTDIR, that the uninstaller worked perfectly. While I wanted it in a different subdirectory, it wasn't critical that it be there, so I just changed the location in my script. It was the easiest solution, and since I basically don't know what I'm doing, that works just fine, lol.

The obvious problem is that if the user moves the uninstaller, then it won't delete the files (or itself) -- it will simply delete the registry entries and proceed to tell the user the uninstallation worked "successfully". I thought about perhaps creating a function that would use an "IfFileExists" to detect if it's in the proper location and abort the install if it isn't, but that seems to be part of the problem I was originally having so I don't anticipate being successful.

The only other complication I see is if the user actually deletes the uninstall .exe. This will be a problem as I have a function that prevents installation over an existing one by reading the registry. So, I haven't thought of a way around that yet.

Again, I appreciate your help.
moho9 is offline   Reply With Quote
Old 18th January 2014, 05:56   #11
JasonFriday13
Major Dude
 
JasonFriday13's Avatar
 
Join Date: May 2005
Location: New Zealand
Posts: 923
Quote:
Originally Posted by moho9 View Post
Well, I found a solution, though I'm not sure it's what either of you were saying.

Taking a closer look at the simplest default installer/uninstaller I could make with HM NIS Edit, I figured out that if I simply left the uninstaller .exe in the $INSTDIR, that the uninstaller worked perfectly. While I wanted it in a different subdirectory, it wasn't critical that it be there, so I just changed the location in my script. It was the easiest solution, and since I basically don't know what I'm doing, that works just fine, lol.
This is exactly what we were talking about, the uninstaller uses the directory it's in for $INSTDIR, which is why your uninstaller didn't work. $INSTDIR can be different between the installer and the uninstaller (usually they are the same), in your case they are different because the uninstaller wasn't written to $INSTDIR.

Quote:
Originally Posted by moho9
The obvious problem is that if the user moves the uninstaller, then it won't delete the files (or itself) -- it will simply delete the registry entries and proceed to tell the user the uninstallation worked "successfully". I thought about perhaps creating a function that would use an "IfFileExists" to detect if it's in the proper location and abort the install if it isn't, but that seems to be part of the problem I was originally having so I don't anticipate being successful.
One way to fix this is to write the install directory to the registry (using WriteRegStr) during the install. Then if the uninstaller is moved it's not such a big problem because in 'Function un.onInit' you can read this install dir from the registry (with ReadRegStr) and use 'StrCpy $INSTDIR $variable_containing_instdir', or whatever variable you read the path into.

For deleting the uninstaller executable, there's a script on the wiki that gets the uninstallers filename, then just use 'Delete $EXEDIR\$variable_containing_the_filename'.

"Only a MouseHelmet will save you from a MouseTrap" -Jason Ross (Me)
NSIS 3 POSIX Ninja
Wiki Profile
JasonFriday13 is offline   Reply With Quote
Old 18th January 2014, 10:46   #12
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Quote:
Originally Posted by moho9 View Post
And, isn't the uninstaller supposed to be reading this information by default when the user launches it?
InstallDirRegKey is for the installer only and it sets the initial value of $INSTDIR; the uninstaller does not use it. It is up to you to save $INSTDIR somewhere and then read it in the uninstaller. The uninstaller's location is used as the initial value for $INSTDIR.

Stu
Afrow UK is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump