Introduction
- A self-extracting archive contains an executable stub added at the beginning, which
handles the archive extraction.
- The ZipArchive Library automatically detects self-extracting archives.
Creating a Self-Extracting Archive
First you need to create a self-extracting executable stub. The following sample
code shows an example of it.
Sample Code
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
CZipArchive zip;
TCHAR szBuff[_MAX_PATH];
if (!::GetModuleFileName(hInstance, szBuff, _MAX_PATH))
return -1;
CZipString szDest;
zip.Open(szBuff, CZipArchive::zipOpenReadOnly);
for (ZIP_INDEX_TYPE i = 0; i < zip.GetCount(); i++)
zip.ExtractFile(i, szDest);
zip.Close();
return 0;
}
Appending Archive to Self-Extracting Stub
To create a self-extracting archive, create a new archive using the
CZipArchive::zipCreateAppend mode and pass the path of your self-extracting
stub to the
CZipArchive::Open(LPCTSTR) method.
Then, you can for example add some files to it. This will create a self-extracting archive
that is compatible with popular archivers.
Sample Code
CZipArchive zip;
zip.Open(_T("C:\\Temp\\my-sf-stub.exe"), CZipArchive::zipCreateAppend);
zip.AddNewFiles(_T("d:\\My Documents"), _T("*.doc"));
zip.Close();
You can later open the archive for modifications. In case you need it, the offset
of the first file in the archive tells you the size of the self-extracting stub:
Sample Code
CZipArchive zip;
zip.Open(_T("C:\\Temp\\my-sf-stub.exe"));
ZIP_SIZE_TYPE stubSize = zip.GetFileInfo(0)->m_uOffset;
zip.Close();
Converting Existing Archive to Self-Extracting Archive
To convert an existing archive into a self-extracting archive, use one of the following
methods:
- CZipArchive::ShiftData() - to make space at the beginning
of the archive for a self-extracting stub. You can then copy your stub into this
free space.
- CZipArchive::PrependData(CZipAbstractFile&, LPCTSTR)
- to copy your self-extracting stub contained in a file (it can be a memory file)
to the beginning of the archive. This method can also change the extension of the
archive (in this case the archive is closed). This method performs necessary shifting
of the data.
- CZipArchive::PrependData(LPCTSTR, LPCTSTR) - behaves
similarly to the above method, but reads a self-extracting stub from a disk file.
All these method create self-extracting archives compatible with popular archivers.
Sample Code
CZipArchive zip;
zip.Open(_T("C:\\Temp\\test.zip"));
zip.PrependData(_T("C:\\Temp\\my-sf-stub.exe"));
Callbacks Called
While shifting data, the
CZipActionCallback::cbMoveData
callback is called. To read more about using callback objects, see
Progress Notifications: Using Callback Objects.
Additional Considerations
For the data shifting and prepending methods to work, the following conditions must
be satisfied:
- The archive must be opened.
- No file must be opened for compression or extraction.
- The archive must not be a segmented archive.
- There must be no bytes before the archive (the CZipArchive::GetBytesBeforeZip()
method should return
0
).
Binary Prepending
You can prepend a self-extracting stub to an existing archive without shifting data,
e.g. using the following DOS command:
copy /b Stub.exe + Archive.zip
SelfExtract.exe