Making an installer with BMX

BlitzMax Forums/BlitzMax Programming/Making an installer with BMX

JoshK(Posted 2012) [#1]
I want to make an installer program I can append data to and have it read it's own file contents and install the programs. I want this to work AFTER the installer program is compiled.

It is possible to just append data to the end of the .exe file. Then you write the start position of the data to the last four bytes of the .exe, and it actually works. However, if the resulting .exe is very big, is takes a long time to start when you double-click it. This is presumably because the entire file is being read into memory before the program starts.

Is there another way to pack files into an existing .exe, like in the resources section or something? Or maybe it is possible to find the position of an incbinned file, and replace it with a block of raw data containing all your files, replacing the file size with the size of your data block?

Any other ideas?


Midimaster(Posted 2012) [#2]
I always use Koriolis ZipStream. In combination with INCBIN you can include a ZIP file, that contains all your files.

This is smaller than INBCIN the files direct.


JoshK(Posted 2012) [#3]
The files have to be added to the compiled .exe AFTER it is compiled. I want to compile the .exe and reuse it as a template, adding different files to it to make different installers.

Last edited 2012


JoshK(Posted 2012) [#4]
I tested with 2 gb on a non-SSD hard drive, and although there is a delay when it starts, it is maybe one or two seconds, and the process only uses 1500 kb memory. So I think my original idea was safe to use.


zzz(Posted 2012) [#5]
Afaik sections have to be explicitly defined in the pe headers for them to be mapped to memory, so just slapping on data at the end should work indeed.

Last edited 2012


BlitzSupport(Posted 2012) [#6]

Then you write the start position of the data to the last four bytes of the .exe, and it actually works


Is this your own method, whereby you seek to the last four bytes then read the offset? It might be quicker if you don't have to do that part, and this article shows (in some ancient form of BASIC) how to read the offset from the executable structure at the start of the file. (See third block of code.)

This Code Archives entry uses the executable file structure, and I believe the IMAGE_DOS_HEADER type there equates to what's in that article. (I suspect the 'INTEGER' type of that old BASIC might have been two bytes.)

Last edited 2012


JoshK(Posted 2012) [#7]
Yeah, I just ended up adding the data begin position at the end of the file. I also added a few other things like the name of the program being installed and some images to show in the installer screens.

If you want to sort out the UAC issues on Windows, use this:
http://www.restuner.com/howto-insert-trust-info-manifest.htm

Last edited 2012


ImaginaryHuman(Posted 2012) [#8]
(sorry I didn't read this whole thread and now what I wrote below is probably irrelevant)

I was working on a screensaver module for Unity and was using Blitz as a compilation wrapper thing ... what I did was, as you said, simply append extra data to the end of the exe file with a code at the end to tell me how big it was. Actually what I did was use the blitz LZMA module to compress several chunks of data and store them in reverse sequence (so that I could scan backwards to read them in order).

To my knowledge, the whole exe did NOT get loaded into memory up-front because the headers etc in the exe file format only told the o/s to read the main exe and its data .... or at least that what seemed to be happening. It's similar (I believe) to what happens when you run a really big app that shows a splash screen really early even though stuff keeps loading - it's because the main portion of the exe is already loaded and can start running and then it proceeds to read more data from the exe file. Correct me if I'm wrong or if the behavior has changed on more recent o/s versions. From what I could tell it seemed like the o/s was only loading the original amount of data, otherwise it should've taken longer.

Still, it sounds like you're encountering a long load so I'm not sure.

I would recommend using LZMA though to pack your data as then the disk load time is reduced and LZMA is quite fast at decompressing.

An idea for working with `incbin` depends on you knowing the final size of your data ahead of time, so this would work as a 1-off kind of thing. If you know the filesize at compile time, write a little utility that loads your file data into a memory bank starting at a slight offset, say 4 or 8 bytes into the bank. Write a codeword into the first few bytes of the bank to identify it - something that doesn't occur elsewhere in the final exe. Then save the bank. Then back in your installer, incbin the appended file. Now your installer can look through `itself` to find the codeword and then you know this is where your data begins in memory. Again I'd recommend combining this with LZMA compression (if it helps).

As far as being able to make a template that you can re-use etc that's much harder because now you have a variable payload size and blitz won't understand how to make the right amount of room for it in the exe. You'd have to recompile the installer each time for each product.

Last edited 2012

Last edited 2012


JoshK(Posted 2012) [#9]
I think when I tried this years ago, I must have been reading the file list at startup, and it was just the number of files that made it take so long to start. I'm not experiencing any problems now, even with a 2 gb EXE.

This is the kind of thing I love about programming Windows stuff.


TaskMaster(Posted 2012) [#10]
Isn't this the sort of thing that will trigger some Anti-Virus programs?


*(Posted 2012) [#11]
@Josh: ya can do that on any OS its not just windows, I have done the base installers (data at end of exe) on Novell Netware, DOS, Linux, OSX and Windows 3.11/95/98/2000/NT/XP/7/8 and they all perform the same.

With each platform its how you lay out the data that gets the end results, on OSX its MUCH more fiddly now with the 'app' stuff BUT it can be done however I would recommend using one of the installer apps for that as sometimes OSX can throw a wobbly as the data doesnt match up with the compiled results.

Last edited 2012