I wrote a stub for making zpaq self extracting archives and added it to the zpaq/unzpaq distribution. http://mattmahoney.net/dc/zpaq103b.zip
To create an archive, copy the stub (zpaqsfx.exe) and use zpaq to append to it ("a" command), for example:
The stub adds about 15 KB. To extract, run the program with the "x" argument, as if extracting with zpaq or unzpaq. If run with no arguments, the extractor lists its contents and gives instructions to extract. I figured this is more "polite" than just filling up your directory with files without any warning. The "x" command works like unzpaq.
copy zpaqsfx.exe calgary.exe
zpaq a calgary.exe calgary\*
You can store filename paths (zpaq ra) but this isn't recommended because the self extractor won't create directories. There is also no check for absolute paths and such, because, well, you are running a .exe and I'm assuming you trust the source
calgary (shows contents)
calgary x (extracts all 14 files, doesn't clobber)
calgary x file1 file2 (extracts 2 files and renames them, clobbers)
(Maybe I'll write a separate program to extract from them, just in case you don't).
The stub is a modified version of unzpaq 1.03 that looks for the archive in argv instead of argv. It that doesn't work, it will try adding ".exe" to the filename, but won't search your PATH. To find the start of the archive, it searches for a 16 byte random string (actually a 128 bit hash of it). When you compile zpaqsfx.cpp to zpaqsfx.exe, you have to append this string, which is in the 16 byte file zpaqsfx.tag. The program doesn't need to know its own size. It should work with different compilers, compiler options, and .exe packers. It will probably work in Linux (I'd be surprised if it didn't) but I have only tested it in Windows (Vista) and upx. It was created with g++ 4.4.0:
g++ -DNDEBUG -O2 -s -fomit-frame-pointer -march=pentiumpro zpaqsfx.cpp
copy/b a.exe+zpaqsfx.tag zpaqsfx.exe