Archived Forum PostQuestion:
Here's the idea: Instead of using Chilkat Zip or "Zip 2 Secure EXE" to create a self-extracting EXE, you would write your own C++ app that is the self-extracting EXE. It would open the .zip that's been appended onto the end of its own EXE. This gives you full control over the user interface of the self-extractor, and makes all things possible. The requirement is that your self-extractor is written in C++ and does not require any external DLLs to run. (It might even be best to write it in VC++ 6.0 to eliminate the dependencies on the VC++ runtimes you'll encounter with VC++ 2010, 2012, etc.)
I'll show an extremely simple example. The example requires the use of Chilkat v9.4.0 because the OpenZip method has been modified to always scan forward in a file to find the start of a .zip (assuming the .zip does not start at byte 0). This allows a .exe with an appended .zip to be passed to OpenZip.
The self-extractor application opens the .zip that is appended to its own EXE.
This example is a very simple console C++ Win32 app, but one could write something more sophisticated with a user interface. The GetModuleFilename Win32 Platform SDK function allows the program to find the path of its own executable. After getting the path, it opens the .exe and unzips.
#include <windows.h>
#include <stdio.h>
#include <CkZip.h>
int selfExtract(void)
{
char myExePath[1024];
GetModuleFileName(0,myExePath,1024);
CkZip zip;
bool success = zip.UnlockComponent("myUnlockCode");
if (!success)
{
printf("%s\n",zip.lastErrorText());
return 1;
}
success = zip.OpenZip(myExePath);
if (!success)
{
printf("%s\n",zip.lastErrorText());
return 1;
}
int numUnzipped = zip.Unzip(".");
if (numUnzipped < 0)
{
printf("%s\n",zip.lastErrorText());
return 1;
}
zip.CloseZip();
return 0;
}
int main(int argc, char* argv[])
{
return selfExtract();
}
The procedure is to first build this program (i.e. create the EXE), then append the .zip to the end of the .exe. Here's a simple C++ program using Chilkat to append a .zip to a .exe:
#include <windows.h>
#include <ckbytedata.h>
#include <ckfileaccess.h>
// This program appends a .zip to the end of a .exe
// The .exe must be a multiple of 4 bytes in length. If it is not, null bytes are
// appended to make the size a multiple of 4.
int main(int argc, char* argv[])
{
const char *exeFile = "C:/Ck2000/intelApps/MyAppInstaller/Release/MyAppInstaller.exe";
CkFileAccess fac;
int exeSize = fac.FileSize(exeFile);
int nZeros = 4 - (exeSize % 4);
if (nZeros < 4)
{
CkByteData zeros;
zeros.appendCharN(0,nZeros);
// Append the zeros to the .exe
zeros.appendFile(exeFile);
}
// Append the .zip to the .exe
CkByteData zipData;
zipData.loadFile("c:/aaworkarea/hamlet.zip");
zipData.appendFile(exeFile);
return 0;
}
After the .zip has been appended, the .exe can be run and it will unzip the attached .zip. Maybe this is too much if you're not a C++ programmer, but it's a good way to create a self-extracting EXE with unrestricted potential.
This was not really a question, but just a post with information. :)