Old 15th August 2008, 11:05   #1
urugan
Junior Member
 
Join Date: Aug 2008
Posts: 3
Rollback

Hello everybody, it's my first post.
I'm doing evaluation on nsis and inno to choose the one that suits me more.
I've read and seen enough, just need one last question answered.
Does NSIS supports rollback functionality?
I mean, if I have a scenario of upgrade, which contains copying a lot of files over existing installation and after that calling some sophisticated sql scripts, which can fail, will it be possible to (depending on sql actions outcome) rollback the whole installation to the point before upgrade?
I am pretty sure Inno has it.
p.s.
I don't want no flamewar, just a simple answer, perhaps with some links.
urugan is offline   Reply With Quote
Old 15th August 2008, 16:30   #2
urugan
Junior Member
 
Join Date: Aug 2008
Posts: 3
oh come on!
Nobody?
urugan is offline   Reply With Quote
Old 15th August 2008, 17:27   #3
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,163
no, there is no rollback, you could copy the original files to a backupdir and "restore" from that if needed

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 15th August 2008, 18:29   #4
urugan
Junior Member
 
Join Date: Aug 2008
Posts: 3
thx man.
I was already trying this route.
In my case it also means copying a db. But it should be do-able...
urugan is offline   Reply With Quote
Old 15th August 2008, 18:39   #5
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
This might help you:
http://nsis.sourceforge.net/Backup_f...e_on_uninstall

Stu
Afrow UK is offline   Reply With Quote
Old 20th August 2008, 20:50   #6
Andrew Wallo
Junior Member
 
Join Date: Mar 2008
Posts: 33
rollback.nsh

I'm working on a nice rollback include. ( Aptly titled rollback.nsh ) Just a set of macros really, but it sets up a log that can be saved to a provided path.... builds the log...as you install or edit files and registry entries... and when you're done you close the "session". Then later you could come back and execute the rollback.

Works well for my application which can't really depend on having a clean folder for its files. So 'rollback' means recopying whatever files I detect that I've stepped on, back into the working folder on a rollback. ( Essentially parsing the log file... for FILE entries, and putting it back where the PATH attribute says to go. )

Maybe we should include a log for SQL calls to? Or better a log to execute SQL files against a database... that might abstract your issue better.

It'd be ready for a demo as a general include, except that I'd like to include the ability to tie in a CallBack on a failed copy.... i.e. If you tried to restore a file it was tied up or something. Currently I have a string that gets read from the log file and passed to ExecWait but that's just a bit limiting and somewhat impractical. I'd rather be able to read a string from the log file and call back a function in the NSIS script... like so:

Function handleErrorWithCustomCallback
MessageBox MB_OK "Handled Error."
FunctionEnd

## SNIP ##
## In some Section or function...
ReadFile $myFile $myCallBackString ; blah blah blah
## myCallBackString now has "handleErrorWithCustomCallback"

Call $myCallBackString ; but this isn't resolving....
; macros seem to do something like this with ${_label} but not quite....

The lack of runtime binding/resolution seems to not resolve this.... or maybe I'm not resolving the var's contents like I should be.... any comments Stu?
Andrew Wallo is offline   Reply With Quote
Old 20th August 2008, 22:03   #7
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Try using GetFunctionAddress.

Stu
Afrow UK is offline   Reply With Quote
Old 21st August 2008, 01:21   #8
Andrew Wallo
Junior Member
 
Join Date: Mar 2008
Posts: 33
Not the answer.... still requries compile time binding.

Sadly, that doesn't seem to work.... for example....

Function testCallback
MessageBox MB_OK "Called it"
FunctionEnd


;--------------------------------
; There are no sections or pages in this installer. It just executes the .onInit and closes.
;
Function .onInit
var /GLOBAL testTheCallback
StrCmp "1" "0" 0 +2
call testCallback ; this so it doesn't zero the code.

MessageBox MB_OK "Testing callback:"
StrCpy $testTheCallback "testCallback"
GetFunctionAddress $R1 $testTheCallback ;Doesnt' work.

###
## WORKS: GetFunctionAddress $R1 "testCallback"
## BUT SINCE ITS READING IT FROM A FILE ITS NOT USEFUL.
#######################################################
Call $R1
FunctionEnd


GetFunctionAddress seems to want the literal function name entered, not some variable.....
Andrew Wallo is offline   Reply With Quote
Old 21st August 2008, 12:53   #9
Joost Verburg
NSIS MUI Dev
 
Join Date: Nov 2001
Posts: 3,717
The actual names of function and variables are not included in the compiled installer.
Joost Verburg is offline   Reply With Quote
Old 21st August 2008, 16:16   #10
Andrew Wallo
Junior Member
 
Join Date: Mar 2008
Posts: 33
agreed......

Considering that we're sort of operating in an Assembly like stack mentality... I understand that the nice readable names get stored merely as a memory location.

Are you saying that there is no runtime-linking to functions based on an evaluated string? i.e...... something like this in a javascript mentality might look like.... ( during runtime... obviously )

myVar = eval("customFunctionName");

Thus, we could use a line like to this to interpret text files into operating instructions at runtime... such as a call back function for some condition.

What you are saying is that there is no way to reference that function abstractly in code during runtime?
Andrew Wallo is offline   Reply With Quote
Old 16th April 2010, 07:47   #11
mgillespie
Member
 
mgillespie's Avatar
 
Join Date: Jul 2003
Posts: 83
Sorry to bump an old thread, but I did have something to contribute.

We are using quite an old version of NSIS, (2.14), with some custom modifications to the NSIS code to provide a primitive (but works for us) automated rollback system.

Deep down in the NSIS core, where the file is actually written to disk, before the write is actually done, we check to see if it already exists, if it does, we append the existing filename with the .previous extension and then write the new file. On uninstall, it's simply a process of recursively scanning the installation folder, if we find a .previous, delete the original file and restore the .previous version.

The whole .previous creation process can be enabled or disabled during the script execution by setting $R9 (this clearly could be improved to make it a keyword)

Anyone want the patch? (the reason we are still using NSIS 2.14 is because of the source changes we made, we don't see any issues with this old NSIS version, and don't want to constantly merge our NSIS, so there is a benefit for us if we can get this patch, or equivalent functionality into NSIS, so we can use standard NSIS)
mgillespie is offline   Reply With Quote
Old 16th April 2010, 07:54   #12
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
There is no need to edit the NSIS sourcecode to get this behaviour. It's extremely simple to do this in script alone. I therefore very much doubt that your patch will be merged into the trunk.
MSG is offline   Reply With Quote
Old 16th April 2010, 11:27   #13
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
It's extremely simple to do this in script alone.
Since when? :x

Not that I'm advocating this patch per se - but unless I missed something, you're going to need quite a bit of code to actually get this sort of behavior out of NSIS. There's probably examples in the wiki that make it easier because you don't have to come up with something from scratch*, but...

For single files, you'd have to define a macro that replaces the File command you'd normally use which...
1. Checks if the file exists
2. If it does, creates a backup*
3. Tries to overwrite the file
3a. If it succeeds - great, done
3b.1 If not, delete the backup
3b.2 Catch the error with custom handling if desired (see some other thread on this)
* and in the backup section check if you can actually back up to the location you want to back up to.

And that's single files. As soon as you use the File command to include multiple files or files recursively, you have to either... A. Drop that construction entirely and make a pre-installer build installer that generates a file inclusion list for the actual installer, or B. First extract the files to a temporary location and instead of using the File command to place the files directly, find the files that were created in the temporary location and use CopyFiles and CreateDirectory instead (further handling is similar to the above).

You'd need these as separate macros as well - or as a single macro but for 'single file' calls you'd have to explicitly indicate that it is such. e.g.
!macro macroname source dest recursive
For a single file would always have to specify the 'recursive' bit as being 'false', '0', or whatever one chooses.
This applies for every parameter in the File command that you'd want to support. Adding support for /x (exclude files) means adding another parameter... now a single file call might end up looking like:
${macroname} "somefile.ext" "$InstDir\somefile.ext" 0 0
Alternatively you'd have to define them before your call.. or callS in which case you have to make sure you don't forget to undefine them afterward.. etc.

It's not impossible, but 'extremely simple' is not how I would choose to describe it in general
Animaether is offline   Reply With Quote
Old 16th April 2010, 14:00   #14
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
Quote:
Originally Posted by Animaether View Post
It's not impossible, but 'extremely simple' is not how I would choose to describe it in general
I was referring to the fact that it mostly requires just a bunch of ${If} statements, which are trivial to code if you're clearheaded enough. But sure, I stand corrected, it takes some effort to get it exactly right. :-)

(You could of course make two macros, one single and one recursive/wildcard...)
MSG is offline   Reply With Quote
Old 16th April 2010, 15:04   #15
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
Originally Posted by MSG View Post
(You could of course make two macros, one single and one recursive/wildcard...)
Well that's something I addressed toward the end... now you want to support /x as well.
So now you need macros:
File
FileR
FileX
FileRX

Now add /a and /nonfatal Granted, those are a little more obscure, but you can see how things quickly tend to explode into a number of macros. Hence why instead one might have something like a context switch...
${NonFatal} true
${FileSomething} a x ...
${FileSomething} b x ...
${FileSomething} c x ...
${NonFatal} False

But you phrased it well when you said
Quote:
it takes some effort to get it exactly right. :-)
Animaether is offline   Reply With Quote
Old 27th April 2010, 14:40   #16
mgillespie
Member
 
mgillespie's Avatar
 
Join Date: Jul 2003
Posts: 83
And this was precisely the reason we decided on a change deep down at file writing level, as it works regardless of how the file is added to the installer :-)
mgillespie is offline   Reply With Quote
Old 27th April 2010, 15:46   #17
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
Originally Posted by mgillespie View Post
And this was precisely the reason we decided on a change deep down at file writing level, as it works regardless of how the file is added to the installer :-)
Only to an extent, though, if I read your original post right:
Quote:
Originally Posted by mgillespie
We check to see if it already exists, if it does, we append the existing filename with the .previous extension and then write the new file.
So what if filename.previous already exists?

Quote:
Originally Posted by mgillespie
On uninstall, it's simply a process of recursively scanning the installation folder, if we find a .previous, delete the original file and restore the .previous version.
And what if 'the original' is not actually -your- original?

Doing it 'right' will never be easy - if even possible at all - but there's certainly room for improvement.
Animaether is offline   Reply With Quote
Old 27th April 2011, 16:09   #18
mathrick
Junior Member
 
Join Date: Apr 2011
Posts: 1
Quote:
Originally Posted by Andrew Wallo View Post
I'm working on a nice rollback include. ( Aptly titled rollback.nsh ) Just a set of macros really, but it sets up a log that can be saved to a provided path.... builds the log...as you install or edit files and registry entries... and when you're done you close the "session". Then later you could come back and execute the rollback.
Quote:
It'd be ready for a demo as a general include, except that I'd like to include the ability to tie in a CallBack on a failed copy.... i.e. If you tried to restore a file it was tied up or something. Currently I have a string that gets read from the log file and passed to ExecWait but that's just a bit limiting and somewhat impractical. I'd rather be able to read a string from the log file and call back a function in the NSIS script... like so:

Function handleErrorWithCustomCallback
MessageBox MB_OK "Handled Error."
FunctionEnd

## SNIP ##
## In some Section or function...
ReadFile $myFile $myCallBackString ; blah blah blah
## myCallBackString now has "handleErrorWithCustomCallback"

Call $myCallBackString ; but this isn't resolving....
; macros seem to do something like this with ${_label} but not quite....

The lack of runtime binding/resolution seems to not resolve this.... or maybe I'm not resolving the var's contents like I should be.... any comments Stu?
Any progress on that? I've coded a macro-based semi-solution which allows registering "callback groups", each containing up to 16 callbacks. See callback.nsh for code, and testcallback.nsi for an example of usage. In exchange I'd really like to see your rollback code :)
Attached Files
File Type: nsh callback.nsh (10.8 KB, 209 views)
File Type: nsi testcallback.nsi (891 Bytes, 200 views)
mathrick 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