Creating a Self-Extracting Zip Archive on a Linux Box

Creating a self-extracting zip archive on a linux box

Your answer can be found at the following page: http://ubuntuforums.org/showthread.php?t=847329 Please note that I do not take credit for anything other than using Google and finding something that sounds logically like it would work. I do not guarantee that this information will work, or that you will be able to find the mentioned materials online anymore. I'm just a fan of Google. I hope this helps.

The problem A few days back I had to
create a Win32 compatible
self-extracting ZIP file for a friend.
Sounds easy, right. The problem was
that I didn't have a Windows machine
nearby and I didn't want to install
any archiving programs under Wine.

NOTE: A freeware ZIP program such as
IZArc under Wine can be used to create
a Win32 self-extracting ZIP file too.
That will not be covered by this
howto, sorry.

The "research" Googling around I found
this forum post dated August 2003.
Reading it I found out that
self-extracting ZIP files are nothing
more but a suitable unzip binary
followed by a normal ZIP file. I used
the unzipsfx.exe included in Info-ZIP
UnZip 5.52.

The link on that post worked a few
days ago so I got my hands on the
unzipsfx.exe that I was looking for.
Today, 2nd July 2008 I found the link
dead. After some googling I didn't
find a working link anywhere. I read
the licence a few times and understood
that I can redistribute the original
unzipsfx.exe with a license included.

Please note that the
unzipsfx-552_win32.tar.gz (80 kB) is
not an official Info-ZIP package and
it includes copyrighted software that
I take no credit for. More info in the
Info-ZIP license that is also included
in the tarball. The source code for
the binaries included can be found
here.

The solution

Step one, getting the unzipsfx.exe and
zip package:
* open the Terminal (in Ubuntu press alt+f2 and type gnome-terminal)
* type in the following commands Code:

wget
http://kolmoskone.homelinux.org/~kaja/kamaa/unzipsfx-552_win32.tar.gz
tar zxf unzipsfx-552_win32.tar.gz sudo
apt-get install zip

Step two, creating a ZIP file in
Ubuntu:
* open the file manager (nautilus) and select the files you want to have
zipped
* right click and select Create an archive (or similar). Select a
location for the ZIP file, using your
home directory is the easiest. Select
type .zip. See man zip for information
on how to create a ZIP file in command
line.

Step three, making the ZIP file
self-extracting
* type in the following commands Code:

cat unzipsfx-552_win32/unzipsfx.exe
MYZIPFILE.zip > mysfxfile.exe zip -A
mysfxfile.exe

mysfxfile.exe can now be opened in any
Win32 compatible system (including for
example Windows XP/2000/Vista and even
Wine in Linux) or ANY ZIP COMPATIBLE
archive program such as file-roller in
Ubuntu.

How do I make a self extract and running installer

Okay I have got it working, hope this information is useful.

  1. First of all I now realize that not only do self-extracting zip start extracting with doubleclick, but they require no extraction application to be installed on the users computer because the extractor code is in the archive itself. This means that you will get a different user experience depending on what you application you use to create the sfx

  2. I went with WinRar as follows, this does not require you to create an sfx file, everything can be created via the gui:

    • Select files, right click and select Add to Archive
    • Use Browse.. to create the archive in the folder above
    • Change Archive Format to Zip
    • Enable Create SFX archive
    • Select Advanced tab
    • Select SFX Options
    • Select Setup tab
    • Enter setup.exe into the Run after Extraction field
    • Select Modes tab
    • Enable Unpack to temporary folder
    • Select text and Icon tab
    • Enter a more appropriate title for your task
    • Select OK
    • Select OK

The resultant exe unzips to a temporary folder and then starts the installer

GCG in ScipOptSuite-7.0.2: Linux self-extracting archive installation lets me start SCIP, but not GCG

I had the same issue and this fixed it for me (although my installation version was v7.0.3).

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SCIPOptSuite-7.0.3-Linux/lib

Note this only applies to the terminal instance the line was run in (so once it's closed you have to run the line again in another terminal instance to reapply this change).

Refer to this link for how to permanently set it if you need this: https://askubuntu.com/questions/58814/how-do-i-add-environment-variables

How to extract last file added to an zip archive

Try this:

unzip /path/to/archive/dec2020.zip $(unzip -l /path/to/archive/dec2020.zip | sort -k2 | tail -5 | head -1 | awk '{ print $4 }')

$() expands the first command and uses the expansion in the second. We list the archive entries in date order and use tail, head and sort to get the line required. We then use awk to print out the file path (the 4th space delimited field)

Alternatively, this can be done with the awk system function to action the unzip.

 unzip -l /path/to/archive/dec2020.zip | sort -k2 | tail -5 | head -1 | awk '{ system("unzip /path/to/archive/dec2020.zip "$4) }'

Self-Extracting Zip: Specify Extraction Path With .exe File

Personally, I had very good experiences with using NSIS as a setup tool. It's a bit more than a SFX but really good to use, rather flexible and free-of-charge.

So I recommend that you do not write your own SFX in C# (aka "re-inventing the wheel") but rather use something existing that is real-world-proofen.

There are, of course, a lot of other installers available.

Creating a zip extractor

DotNetZip is a library that allows managed code apps to read or write zip files. One thing it allows you to do is produce a self-extracting archive (SFX).

In C#, the code to produce an SFX archive with DotNetZip looks like this:

using (ZipFile zip1 = new ZipFile())
{
// zip up a directory
zip1.AddDirectory("C:\\project1\\datafiles", "data");
zip1.Comment = "This will be embedded into a self-extracting exe";
zip1.AddEntry("Readme.txt", "This is content for a 'Readme' file that will appear in the zip.");
zip1.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.WinFormsApplication);
}

You choose how to shape the folder hierarchy in the ZIP file. The only rule is, upon extracting, the extraction happens to a particular root or parent folder. (You cannot extract to 7 different directories scattered about the filesystem)

The resulting EXE requires the .NET Framework 2.0 or later in order to run, but nothing else.

The SFX/EXE is also a regular Zip file that you can read and extract with WinZip, or other zip tools, including Windows Explorer "Compressed Folders".

The SFX composes with the other zip features, including

  • WinZip AES encryption - so you can encrypt the thing and only allow unpacking for someone who knows the password.
  • ZIP64 for very large archives.
  • Unicode, for filenames outside of the normal ~ASCII range.
  • restoration of File attributes, timestamps, etc.

In DotNetZip, there are two possible flavors of SFX that you can generate: a console app or a WinForms app. The WinForms UI is generated for you - nothing to write or design. It's simple and utilitarian, and looks like this:

alt text

The console flavor is more suited to being used in a script, or in a headless (no UI) scenario.


There are a bunch of options when producing the SFX, like:

  • whether to open Explorer after unpacking
  • a command to execute after unpack (the command can be part of what was unpacked)
  • optionally remove all files after the 'execute on unpack' command completes successfully. Nice for a patch utility.
  • whether to overwrite existing files
  • the Win32 icon to use for the SFX EXE, or just accept the default
  • a default extract directory, which can be based on the user's environment, eg %USERPROFILE%.
  • "quiet" mode, which means when it runs, it offers either no UI at all if you are using a console app, or only a simple progress bar if using the WinForms flavor. There are no buttons to click - this SFX just unpacks automatically.

All these options for how the SFX will behave is accessible via the DotNetZip class library interface.


If you don't like the UI or the working model for the built-in SFX capability, there's an easy way to provide your own self-extractor UI + logic. For example you could build an app in WPF and make it all snazzy and visually dyanmic. The way it works is pretty simple: in the code that produces the SFX, copy your unzip stub EXE (WinForms, WPF, or whatever) to an output stream, and then, without closing the stream, save the Zip file to the same stream. It looks like this in VB:

Public Shared Function Main(ByVal args As String()) As Integer
Dim sfxStub As String = "my-sfx-stub.exe"
Dim outputFile As String = "my-sfx-archive.exe"
Dim directoryToZip As String = "c:\directory\to\ZIP"
Dim buffer As Byte() = New Byte(4000){}
Dim n As Integer = 1
Using output As System.IO.Stream = File.Open(outputFile, FileMode.Create)
'' copy the contents of the sfx stub to the output stream
Using input As System.IO.Stream = File.Open(sfxStub, FileMode.Open)
While n <> 0
n = input.Read(buffer, 0, buffer.Length)
If n <> 0 Then
output.Write(buffer, 0, n)
End If
End While
End Using
'' now save the zip file to the same stream
Using zp As New ZipFile
zp.AddFiles(Directory.GetFiles(directoryToZip), False, "")
zp.Save(output)
End Using
End Using
End Function

The resulting file created by this code is both an EXE and a ZIP file. The stub EXE must read from itself in order to extract. In the example from above, the code for the my-sfx-stub.exe program could be something as simple as this:

Dim a As Assembly = Assembly.GetExecutingAssembly
Try
'' read myself as a zip file
Using zip As ZipFile = ZipFile.Read(a.Location)
Dim entry As ZipEntry
For Each entry in zip
'' extract here, or add to a listBox, etc.
'' listBox1.Items.Add(entry.FileName)
Next
End Using
Catch
MessageBox.Show("-No embedded zip file.-")
End Try

A custom SFX constructed in this simple way will have a dependency on the DotNetZip DLL. To avoid this, and to produce a single self-contained EXE that can extract with no additional DLL dependencies, you can use ILMerge, or, embed the DotNetZip DLL as a resource and use an AssemblyResolver event to load it from the embedded resources.

If you have questions, you can ask on the DotNetZip forums.



Related Topics



Leave a reply



Submit