Archive: How to use a zip file as source for nsi script?


How to use a zip file as source for nsi script?
  I've tried searching the board for zip, but I get no results (I have a hard time believing I'm the first to need this). How do I use a zip file as the input source? I tried looking at the zip2exe nsh files, but didn't see anything that would help me there. I've also looked through the examples on the wiki, but I still didn't see anything that addressed how to do this. I feel like I'm missing the elephant in the room.

Ryan


define "use a zip file as the input source"?

you can include a zip file 'as is' (i.e. the zip file will be placed on the user's computer) just using:

Section
SetOutpath"$INSTDIR"
File "c:\path\somefile.zip"
SectionEnd
>
You can include the files within that zip file by first extracting all of the files from the zip file on the compiling machine, then include those, so that the individual files will be placed on the user's machine:

SectionEnd 

>
( you could use defines for the temp path. The reason I'm not in this example is because it makes it easy to forget the define, resulting in the del command being run on your drive root; Bad Thing™ )

Or you can include the ZIP file 'as is', extract that to the user's drive (temporarily) and then extract the files from that ZIP file using one of the zip handling plugins. E.g. http://nsis.sourceforge.net/Nsisunz_plug-in:

Section
InitPluginsDir
SetOutpath "$PLUGINSDIR"
File "c:\path\somefile.zip"
SetOutpath "$INSTDIR"
nsisunz::Unzip "$PLUGINSDIR\somefile.zip" "$INSTDIR"
Pop $0
SectionEnd
>
If you meant anything else, you'll have to be more specific :)

Originally posted by Animaether
define "use a zip file as the input source"?
I think your second or third solution is what I'm looking for. I've got a program that is built on a linux server and the output is a zip. The output on the users machine will be the contents of the zip. I am thinking it would be better to have the extract operation done once on the build server instead of every time on the users machine at install. Any input as to which of the last two you'd recommend?

Using an unzip plugin is not recommended unless you specifically don't want to put your files in the installer exe itself. Therefore, his second solution (not the third) is the best in almost all cases.


Yup - I would recommend the second one as well. This has several benefits...
- faster install for the end-user
- better compression of your installer (who knows what level of compression the ZIP used, but re-compressing the archive itself won't help much)
- accurate install sizes (for 'required space' calculations)
- more detailed installation progress (as instead of one, potentially big, file, each file within the ZIP is counted toward progress)
and that's just off the top of my head.

The only time I've used one of the unzip plugins was when the content itself was dynamically retrieved (from an internet location), and thus had little choice :)


Thanks guys, #2 it is then.

Animaether, your comment about the progress bar brought up another question I had, and perhaps it should be in it's own thread (I must admit, I haven't done any research on this problem yet). I used the EclipseNSIS to generate my install script, and the uninstall progress bar sits on 0%, then it jumps to 100% when it's done. How do I go about getting an accurate progress bar on uninstall?


That should indeed be a separate thread - be sure to include what code it might currently be using to uninstall the files as that's directly related to the question.. every code statement in an uninstall section should add to the total progress so odds are the code it's using now has too few code statements.


So an additional related question, but again it could probably use it's own thread as well.

In relation to this code

!system 'del /S /Q "c:\temppath\*.*"'
!system 'pkunzip -d "c:\path\somefile.zip" "c:\temppath'


In the NSIS manual:
"$TEMP

The system temporary directory (usually C:\Windows\Temp but detected at runtime)."

Is there a similar variable that I can use to detect the temp directory of the machine the script is being compiled on? The reason I ask, is I want to integrate this as the last step in our build, and the build is done on a linux server (so the temp dir would be /tmp). I've successfully built the compiler to run on linux and have manually extracted the zip and built my installer on the build server. But, I'd like to have the temp that that I extract the files to be calculated such that I could use the same script to build on windows, if needed.

Actually, I don't think it'll matter. I need to use system dependent calls to delete and unzip anyways.


Well, just in case..

Iit's hidden away a bit in the documentation, but:

5.3 Read environment variables
5.3.1 $%envVarName%
$%envVarName% will be replaced on compile time by the environment variable envVarName.
So the TEMP folder is $%temp% . Most of my test scripts nowadays use e.g. `OutFile "$%temp%\temp.exe"`

Originally posted by Animaether
Well, just in case..

Iit's hidden away a bit in the documentation, but:


So the TEMP folder is $%temp% . Most of my test scripts nowadays use e.g. `OutFile "$%temp%\temp.exe"`
Cool, thanks for the tip. I'm going to go for gold now, but is it possible to detect the OS that the script is being compiled on?

off the top of my head.. I'd say 'no'. Though perhaps an environment variable that exists on one but not on the other would be an indication.

E.g.


/* wrong code here */ 

You'd have to check whether %APPDATA% is valid on your building machine(s).. I wouldn't know if that's one common to all windows machines.

Edit: errrr that code was all kinds of wrong.

Well shoot. I was hoping that "$%foobar%" would result in an empty "" due to the environment variable not existing. I suppose it's logical not to do that, as that would mean it'd be impossible to detect empty-but-existing environment variables. On the down side, I'm not sure how to detect a varying environment variable existing or not at compile-time given this behavior. Run-time would be easier, but if you need to detecting the compiling OS, I'd suspect that wouldn't help much :)

If the value of the environment variable is know, then it's easier, of course.

!define test "$%OS%"

!include "FileFunc.nsh"

OutFile "$%temp%\temp.exe"
Section
!if ${test} == "Windows_NT"
MessageBox MB_OK "WINDOWS"
!else
MessageBox MB_OK "NOT WINDOWS"
!endif
SectionEnd
>
Same note as previous post applies.. no idea if that 'OS' env variable is valid on all your compiling Windows machines.

Thanks, all our machines are XP, so the Windows_NT should work. Probably a better way is for me to define a var that is only on my Linux build and key off of that. But thanks for your help, I basically got it setup so the same script builds on both machines.


yup - if you have full access, then setting your own variable would be safest.

It's also entirely possible that there -is- a dedicated construct in NSIS somewhere that lets you detect the OS at compile-time.. just not seeing one :)


hurray!
Anders mentioned in http://forums.winamp.com/showthread....71#post2716671 that there -is- actually a define to determine the compiling platform;


!endif 

This isn't fully documented (it's in the version history/release notes), but there you go :)

Thanks for the help, but (I hate to say this) it turns out I may not need any of this. I had the guy who manages the build server setup the linux side of things and he kicks off the build with ant. The ant script manages deleting the dir and unzipping the zip file. And the File location, version numbers, etc. are passed in as makensis command parameters.


That's okay.. now that it's all here, the next time somebody asks, we can tell them to use the Search ;)