I would like to store some XML program preferences as a resource in a Delphi application. The resource would be modified based on user changes. I have no problem creating the XML and loading it as a resource, and can modify the xmlDocument that I load it into, but I don't know how to write the document back. Is this even possible? I would prefer not to end up with 2 files in the end (.exe and .xml).
-
2This is not how you normally manage your settings. May I ask why do not want an external XML file? A settings XML file should be saved in `%APPDATA%/CompanyName/ProductName/ProductVersion`. You could also use the registry to save data. In the case of a portable application living on a USB mass-storage device, you should save the XML file next to the EXE file on the USB device. If, for some strange reason, you really need the 'embedded' XML to change, you will probably need *a second executable*. – Andreas Rejbrand Oct 19 '11 at 00:42
-
1Don't do this. Put the settings in a separate file. – David Heffernan Oct 19 '11 at 06:12
-
Even if it was easy to accomplish, it won't work if the user has no rights to modify the executable (only users with administrators privileges should have them), and by default the program files directory has such settings. Not only you should not modify the executable, but you shouldn't write the xml file in the same folder as the exe (which may not be writable by the user). Unprotected executables are what makes a system vulnerable from a security point of view. – Oct 19 '11 at 10:36
-
I see the problem... I was just thinking from a mac perspective of having the convenience of everything being in a self contained package, with plists, etc. I guess the mac .app package is not really one binary though, so it is a different matter. I just like the idea of the self contained, portable executable but maybe I will use a seperate file – Joe Oct 19 '11 at 16:55
2 Answers
The answer is both yes and no.
Yes, it is possible to update resources in a binary using Windows API routines. This link to BeginUpdateResource() should get you on the right track on that score.
However, you will note the following condition on the use of BeginUpdateResource():
"The binary file in which to update resources. An application must be able to obtain write-access to this file; the file referenced by pFileName cannot be currently executing."
In other words, it is not possible for an application to simply update it's own resources while running.
There are a number of strategies you could employ to achieve what you want - or something close enough to it as to be satisfactory. Which is most appropriate will depend on your precise needs.
Of the multitude of solutions, two might be:
1) Maintain all such resources in a DLL (resource only DLL - containing no actual code as such) which you open only when specifically loading resources (or updating them). Thus at the time you wish to write a resource back to the DLL you should be able to get the required write-lock.
or
2) When you need to update a resource rename the current running EXE to something like "myapp.OLD", copy it so that you have a new file with the current name "myapp.exe". You can then update "myapp.exe" because it is actually "myapp.old" that is executing.
This second approach is quite messy and has a "nasty smell" but is a technique that is (or used to be) quite commonly used by auto-updaters, for example. Obviously will involve a restart of your app at some point if the current running code is to make use of the updated resources in the modified EXE, so it may not be appropriate to your needs.

- 22,162
- 2
- 42
- 70
Something else to consider is that anti-virus software may flag the activity as suspicious.
Thinking about Deltics' answer I thought you could also create a console application that writes your resource back to the main exe. So your main exe saves it's changes to a file and also extracts the console app. When the main application terminates it calls the console app. The console app waits for a short period of time and then binds the resource file to the main executable, deletes the resource file and itself. The console app could do a check to make sure that the resource file was written successfully and, if not, leave the resource file open. The main executable could see the resource file upon start up and use it instead of the embedded file - as a safeguard.
All of this assumes a single user application.
-
Can a console app delete itself? (If not, the console app can start the main executable with a flag telling it to delete the console app and then terminate.) – Andreas Rejbrand Oct 19 '11 at 01:33
-
I'm not entirely sure. I know batch files can delete themselves. But maybe they are special cases. – Oct 19 '11 at 06:09
-
I just tried it, and it didn't work. A batch file is not an exectuable program, or a process. Rather, it is a 'script' being interpreted by a real executable program (a real process). – Andreas Rejbrand Oct 19 '11 at 11:17
-
If you tried it, @Andreas, you didn't try hard enough: [Can a program delete its own executable?](http://stackoverflow.com/questions/1606140/can-a-program-delete-its-own-executable) – Rob Kennedy Oct 19 '11 at 12:31
-
Bute the question is: can a user delete an executable? In a proper set up system, the answer is no. – Oct 19 '11 at 12:47