Archive: Upgrade_Macro Corrected


Upgrade_Macro Corrected
  Hi
Found and corrected a bug in the Update_macro .

Now it also works for changes in minor version numbers


Can someone please include that in the next release....


Here is one that combines yours with CodeSquid's and my fix that seems to do it all!


Damn, the attachment failed. Let's try it again.


I have part modified the already modified UpgradeDLL Macro, to add a prompt (if defined) to ask the user "Do you want to overwrite this file" type of thing.

I've also modifed it so that the push described in usage isn't required anymore.

You can now run the macro like:

!insertmacro UpgradeDLL "atl.dll" "$SYSDIR\\atl.dll" "PARANOID"

>!insertmacro UpgradeDLL "atl.dll" "$SYSDIR\\atl.dll" "EASYGOING"
The first one prompts the user, the second one doesn't.

Now, it still needs work, and the reason is that I haev replaced all the $0 with ${DLL_LOCATION} for usage changes above, so since I'm not really confident working the stack, I haven't changed any other vars or the push/pop's in the macro.

Perhaps someone could have a look at the attachment, and make the necessary changes.

BTW, if the changes I've made are utter rubbish, please let me know!

Macros v Functions
  Just a quick query, but if this were a function would it create less bloat than being a macro.

What I mean is, does the macro get inserted into the code (during compile) every time it is called? and does this happen with functions?

The reason I ask, is I'm playing with an installer that will add some 25 DLL/OCX/EXE's that I may have to run through this, so I'm just thinking of trying to keep the size down.


Yes a macro is inserted every time it is called. You can see this if you create a simple macro that has a label in it. If you !insertmacro the simple macro twice in a row in the same scope the compiler moans about a duplicate defined label.


More mods
  I've made another modification to the macro to allow for a path to the file.

The macro would now be called with:

!insertmacro UpgradeDLL "D:\\DEV\\Poject\\" "atl.dll" "$SYSDIR\\\atl.dll" "PARANOID"

>!insertmacro UpgradeDLL "D:\\\DEV\\\Poject\\\" "atl.dll" "$SYSDIRatl.dll" "EASYGOING"
>
And the changes to the "File/s" are:


File /oname=$5 "${DLL_FILE_PATH}${DLL_NAME}"

>; and
>File /oname=${DLL_LOCATION} "${DLL_FILE_PATH}${DLL_NAME}"
I hope I aint barking up the wroong tree here, but this will make the macro more flexible regarding the location of "File"

Does this make sense?

(modified script attached)

Simon,

The 'GetDLLVersionLocal' and 'File' commands in there stop the whole thing being a function, as the filenames to those commands need to be fixed at script compile time, which isn't possible with something like "File $1".

As for $0 - you can safely just remove the "Exch $0" and "Pop $0" lines now that it is not used.

Back to macro/function - everything other than the commands mentioned would be perfectly fine in a function. Maybe things can be changed so that those bits are in a function with a small macro to perform the File commands before passing on to the function.

I could have a go at doing that if you like, but you'd have to test it ;)

--
Dave.


Thanks!

Testing something like this is tricky. I test other software, and when messing with windows system files, it can get ugly...thankfully it wasn't me building the installers (IS...uggh), but we did kill a few systems!

Anyhoo, I'm obviously trying to do this because I AM intending to use it, and test it of course, so I'll give it a go.

What I'm essentially trying to do is build a macro that will handle all file installations, by checking versions, or file dates.

I think ultimately this would be best handled in 2 separate macros, but I'm also thinking, if I can't get a version of the file, I'd like to fallback and check the date of the file.

Now, its getting tricky again, and also because, if I'm replacing these system files, I want to back them up, so when I uninstall I can restore the system to its original state.

I've built the backup stuff into the macro already - another define (BACKUP or NOT) - the files goto $INSTDIR\install_backup if they are replaced.

So now I need a macro that will work for the uninstaller, which will firstly, check if the file that replaced the original during the install, is still the same file, and not something installed by another app since....if so, then dont restore.

Then copy the files back over their replacements setting all the reg stuff and reboot flags.

It's kinda like building a wrapper for installing and uninstalling files, safely, and ensuring you only install what you need...handy for online installs.

BUT, when you think like that, it would be much more sensible to do to all the version/date checking first, write that info to an ini file, then check the versions of all the existing files (if any) from the INI, against another INI, containing all the info of the files your installing. This way, if the installer IS an online installer (or not), all the operations can be grouped: FileCheck, File Copy/download, UnReg(if needed), UnRegShared(if needed), backup, FileRename, Reg(if needed), RegShared(if needed), etc. and then in reverse for the uninstaller :-).

Don't ya just love Saturday nights!! :-(

I've attached what I have for now...if anyone has ideas for the above-mentioned, or the attached, please don't hold back!


Here's a function-ised version, as promised. It will certainly reduce the overhead per-dll, but there are a couple of question marks over it. (I haven't even attempted to compile it, for one!)

Now there's just one File command, which is always performed and to a temporary name. Maybe this could be undesirable - extracting lots of DLLs which may turn out not to be needed, which are then deleted.

The DLL version of the new file is now taken by using GetDLLVersion on the extracted temporary file. I don't know if not having a .DLL extension (or whatever) will upset GetDLLVersion. If so, I suppose the original GetDLLVersionLocal could be restored as part of the small macro stub.

Anyway, see what you think. If you do start going towards the multi-stage route you describe, I'll certainly be interested in how you get on (although I don't have to deal with DLLs in my installers) (thankfully!).

--
Dave.


Nice one Dave
  Thanks!

I have tried to break it up into the groups as mentioned in the previous post, and so far it looks good (I think).

I have NOT tested it yet, but have attached it here to see if you can spot anything stooopid before I go any further.

It looks like this is building into a nice utility!!

Please have a look and let me know what you think...suggestions are very welcome!

Thanks again!


You've been busy for a Sunday afternoon...
  Ok, initial thoughts (although I've not had time to study it yet).


Anyway, I've already spent more time than I was planning to for now... :p

Have fun!

Dave.

Thanks once again Dave!

I have removed the !undef's as suggested, and hopefully tidied up the push/pops into the right order, as well as fix some typos and bits and pieces.

Regarding the version numbers, I believe these are DWORD's and 32bit, so they have a maxlength (if I'm not mistaken?), which when concatenated and added into a INI file seems to be OK from past experience using this method.

The GetTempFile could probably be done away with, but may be useful for extending...who knows. I think it should be OK as is.

I've aslo made some further changes to allow definiton of the install_type, so that when calling the macro you can choose INSIDE, MEDIA, or DOWNLOAD to decide where you want to install from, and also a cleanup function.

I've attached for anyone to see!


i'm a little new at this and i love this awesome tool. but i need a little help, please. you seem to have accomplished here just what i've been trying to figure out. i have downloaded the file you attached here. but i am not sure what to do with it.

it looks like it needs busted into at least 2 files (.inc files). it also looks like some of the code then goes directly in my .nsi file.

where do the .inc files need to be... in the NSIS directory or in the project directory for the .nsi file?

which parts of the file go where?

sorry if this is mundane. i just stumbled onto NSIS a few days ago and am trying to figure it all out on my own.

thanks,
kingfishers


.inc files, or .nsh files (the extension doesn't really matter) are supposed to be included into your script using !include. When you use !include the pre-processor will just copy the file into your file. This allows you to save space and to change just one file if you find a bug.

To use the macro in your script (after you have included the .inc file) just use !insertmacro like exampled above.


What state is this in?
  Hi - what's the deal with this upgrade macro stuff, is it in a usable state? Basically if it's good and working I'd like to update the stuff on my archive site but it looks like a lot of ideas have been thrown around on this thread and I don't want to put a page up (or update existing material) if I'm not sure about (a) what this stuff is actually capable of now and (b) if it actually works.


i'm a little slow here. i'm not sure i get it yet.

which directory do the .inc files go... i think they must go in the project directory with the .nsi file.

any other advice on how to use this?

like... there isn't a way to define this all once and call it generically by passing the parameter for the name of the dll to upgrade??


thanks,
kingfishers


It doesn't matter where you put the file as long as you remember where you put it :D
It is best to put it in the project directory because then you don't need to give the full path to it, just the relative.

When a file is included it will be processed by NSIS as well so every function/macro in it will be available in your script too. All you need to do is add !insertmacro if it is a macro or Call if it is a function. See the above examples.

If you still don't understand try reading the documentation of NSIS first (makensis.htm). Focus on macros and !include in the documentation. If you still don't understand after the documentation you are more than welcome to ask again.


I have some scripts that I can contribute Sunjammer...just got to take out my progrma specific stuff.

They are a bit incomplete from what I can remember as I had to give the project a back seat for the moment, but'll dig them out, and post, or email to you.

Simon


Improved UpgradeDLL macro+functions
  Hi pals,

After few days of work I put together this (see attachment).
It is in general a macro but with just minimal overhead
because the most of code is contained in a function.
Please have a look at it and test it as much as possible.
It should work with most of DLL and OCX files.
You will need an external plugin "x18sysinfoV0.1.dll" available
from Sunjammer's webpage. I'm using its GetFileVersion function
because it returns the most compact file version information
i.e. always (AFAIK) "MAJOR.MINOR.REVISION.BUILD" formatted number.
Any additional work like adding and removing shared DLL's must
be done separately after macro code finished.
Please note that my macro uses $R0 for temporary local file so
don't forget to save it's content if you need it ;)

Feel free to respond or contribute to this :D


Additional small improvements
  -added few lines there -> now your $R0 is preserved inside the macro
-added two functions+comments from other sources (AddSharedDLL,
un.RemoveSharedDLL)
Hope you find it helpful!


This is my personal version of the UpgradeDLL macro... I made it at the same time as Kypec. However, it does not need any additional plugins like his version.
Hope you like it.


I'm a newbie in using NSIS and wrote a simple install script which installes a ActiveX Object... now i can't get the uninstall to work cause the .dll is in use while uninstalling !!!

Any tips or suggestions ?!

Here's my current script


Sorry... i found a way which seems to work ;)

THX anyway.