How do I write files to an executable for Win/Mac/Linux. I mean a file of any type. For example, a picture, a text file. This is so that the users of my software get a single executable file containing all of the required files for an application. So the app does not rely on any external files. I do not mind having to load the files into the executable at runtime and then saving the files built-in that way.
Well, this is a bundle of worms… I’m pretty sure that I learnt how to do this the hard way for Mac and Windows (I don’t have any such experience with Linux).
I use inno setup for windows. This will install fonts and other files in the application data folder. It’s a lot easier on Windows than Mac.
For Mac, there’s something that is called a bundle. This means that every application has it’s files attached to it’s insides. Every application you see in you application’s folder can be right clicked and you see that it has a package content. Apparently, when you use an install program to install your program, you need to install the bundle. Apparently there’s some code that will help it work more like IInosetup - but I don’t know it.
basically, you want to put your additional files in a folder in resources. Then at install time, copy that folder to application support (preferably in a folder with the same name as the software).
The fonts can be embedded (check my other posts to see how to do that).
I don’t know how to add fonts’ via install to the font folder yet - so if you find a way to do, let us know
Christian has it right.
To simplify matters (at least it feels simpler for me), I compress all my support files into a zip file.
Drag that into the project the same way that you would a picture.
once there, you can access it as a string variable.
Create an output stream, and write that string to the output file unmodified.
Then in my project, I unzip it, but you can do a file at a time if you like.
This is my ‘get the zip file out of the app and onto the disc’ code"
(support.zip was dragged into my project. Once there, Xojo refers to it as an object called ‘support’)
[code]
dim b as BinaryStream=specialfolder.documents.child( “support.zip”).CreateBinaryFile("")
b.Write support
b.close[/code]
dim fout as folderitem = app.executablefile.parent.parent.child("Resources").child("fontfilename.ttf")
chemin = fout.ShellPath
s = New Shell
s.Execute("cp "+chemin+" /library/fonts" )
That you are denied access to /Library is no surprise at all… and I doubt seriously that a declare or anything else will allow you to modify “system” level files without the users direct interaction
What are you trying to do exactly? If you are trying to make the project create stand alone applications with pictures and other resources (I think thats what you mean by an executable file) then good luck to you, you will probably have to create a compiler of some sort to make the executable.
For windows you have to write an helper app. This helper app puts the desired file into the executable. You convert any file to a string, and put the string between delimiters. Then you open an executable file and position the string between the to delimiters (i.e. $$##) and write it to the end of the executable (that is before the last byte). The executable itself (the one with the payload) reads it’s own binary stream and checks wether any specific delimiters are present. If so, convert the string between the delimiters to a file.
This is how self executable zip files are created. I have some code in Delphi available.
That’s way more convoluted than it needs to be. When you drag a file into your project, it becomes a named constant. You simply write it out to disk in app.Open. No need for helper apps or arcane delimiters or parsing an executable.
Say you have your files in a zip file called MyResources.zip. Drag that file into your project, and you get a constant named MyResources which is a string containing the contents of the file. To write it back out is
dim f as FolderItem = SpecialFolder.ApplicationData.Child("myapp").Child("MyResources.zip")
dim t as TextOutputStream = t.Open(f)
t.Write MyResources
[quote=56270:@Tim Hare]Say you have your files in a zip file called MyResources.zip. Drag that file into your project, and you get a constant named MyResources which is a string containing the contents of the file. To write it back out is
dim f as FolderItem = SpecialFolder.ApplicationData.Child("myapp").Child("MyResources.zip")
dim t as TextOutputStream = t.Open(f)
t.Write MyResources
[/quote]
Thats much simpler than I thought !
And it saves a lot of hassle to manage default data files. Up until now, I managed such files under Windows through an install program, but this is one thousand times easier !