Implement a self extracting archive?

Tag: self-extracting Author: gy2002g31 Date: 2012-08-10

I know i can use 7z or winrar but i want to learn this for myself.

How would i implement a self extracting archive? I can use C# or C++ but let me run down the problem.

When i open the exe i need some kind of GUI asking where to extract the files. Once the user says ok I should obviously extract them. I implemented a simple example in C# winforms already BUT my problem is HOW do i get the filenames and binary of the files into an exe?

One upon a time i ask Is it safe to add extra data to end of exe? and the answer suggested if i just add data to the end of the exe it may be picked up by a virus scanner. Now its pretty easy to write the length of the archive as the last 4bytes and just append the data to my generic exe and i do believe my process can read my own exe so this could work. But it feels hacky and i rather not have people accuse me of writing virus just because i am using this technique. Whats the proper way to implement this?

Note: I checked the self-extracting tag and many of the question is how to manipulate self extracting and not how to implement. Except this one which is asking something else Self-extracting self-checking executable

-edit- I made two self extracting with 7z and compared them. It looks like... well it IS the 7z.sfx file but with a regular 7z archive appended. So... there is nothing wrong with doing this? Is there a better way? I'm targeting windows and can use the C# compiler to help but i don't know how much extra work or how difficult it may be programmatically and maybe adding data to end of exe isnt bad?

It depends upon your operating system a lot. And self extracting archives may be security issues....
@BasileStarynkevitch running a exe may be a security concern...

Other Answer1

It is possible. I used the following technique once, when we needed to distribute updates for the application, but the computers were configured so that the end user had no permissions to change application files. The update was supposed to log on to administrator account and update required files (so we came across identical problem: how to distribute many files as a single executable).

The solution were file resources in C#. All you need to do is:

  1. Create a resource file in your C# project (file ending with .resx).
  2. Add new resource of type "file". You can easily add existing files as byte[] resources.
  3. In program you can simply extract resource as file:
System.IO.FileStream file = new System.IO.FileStream("C:\\PathToFile",
System.IO.BinaryWriter writer = new System.IO.BinaryWriter(file);
writer.Write(UpdateApplication.Data.DataValue, 0, UpdateApplication.Data.DataValue.Length);

(Here UpdateApplication.Data denotes binary resource).

Our solution lacked compression, but I believe this is easily achieved with libraries such as C#ZipLib.

I hope this solution is virus-scanner-safe, as this method creates complete, valid executable file.


I tried this. I couldnt figure out if it was possible to enum the resource file. I tested with two files and i had to by hand build an array to pass to an extract function. I was actually googling if i can build a csproj file moments ago before i read this. Is it possible to enum files? also how do i programatically make the resource file?
Sorry but I didn't ever need to go that far - so I don't know. But I believe it is out of range of your original question though.
Ah... And you do not need to have .csproj file to compile C# code. Both .cs and .resx files are plain text, so you can construct them programmatically, and compile using csc (or maybe MSBuild).
Have you looked at the resource file? Its complex...
OK, I removed part about automated solution. Nevermind it.