Click here to Skip to main content
Click here to Skip to main content
Go to top

XML Application Profile Class

, 27 Jan 2007
Rate this:
Please Sign up or sign in to vote.
Implement XML application profiles that are similar (but not too similar) to using INI files

Introduction

I hate putting stuff in the registry. It's not portable, it just adds bulk that's only needed by my application, and it's problematic to backup in case you want to move the app to another machine or easily recover from a reformat/reinstall of Windows. However, every time I mention "put it in an INI file", all of the zealots here on CP complain the INI files are obsolete, and we should always use the registry. Yeah, right, blah blah blah.

I will however admit that INI files are limited in their functionality in a number of ways. They can't be bigger than 64k in size, and data items can be no longer than 256 characters. They can also be difficult to use if you want to do anything more than simply setting/getting data from them. Finally, Microsoft could, at any time, remove the API functions that support them. These are the primary reasons that I wrote the CProfile class.

The CProfile class

This class reads XML files that are formatted in a style similar to INI files. In other words, give the following INI file contents:

    [GENERAL]
    setting1=0
    setting2=test
    [SPECIAL]
    setting1=spider
    setting2=0.12345

... the XML version supported by CProfile would look like this:

<xml>
    <GENERAL>
        <setting1>0</setting1>
        <setting2>test</setting2>
    </GENERAL>
    <SPECIAL>
        <setting1>spider</setting1>
        <setting2>0.12345</setting2>
    </SPECIAL>
</xml>

Since the class is simply trying to emulate the functionality of INI files, all top-level nodes are considered to be evquivalant to INI sections, and each "section" contains one or more child nodes (the same thig as INI "keys"). Child nodes under the keys are ignored - remember, we're just emulating INI files, not an all-encompassing XML file reader. I kept this within the context of an INI file because that's all I need. If you want to make this all-encompassing, have at it, but don't ask me to do it for you. You're a programmer - make it fit your needs.

Inner Workings

CProfile maintains a CTypedPtrArray of profile items. Each profile item contains three CStrings - its section, its key name, and its value. Converting to and from the desired intrinsic type is handled in a series of overloaded Set/Get functions.

The class uses MSXML.DLL and imports the typelib. This way, I don't have to worry about any weird (and often unreliable) XML parsing classes that may only partially implement what's needed to properly parse a XML file. The only thing you have to remember to do is to call CoInitialize() before you call the CProfile::Load() function (and remember to call CoUninitialize() before exiting your app). I just stick a call to CoInitialize() at the top of my InitInstance() function, and CoUninitialize() in my ExitInstance() function - nice and tidy.

Using CProfile

Using CProfile is a simple matter of creating a variable somewhere in your application like so:

#include <span class="code-string">"Profile.h"</span>

CProfile m_profile;

...and then loading the file:

m_profile.Load("");

When you call CProfile::Load(), you need to supply string that represents a file name. If the filename is blank or is not a complete path/filename, the class will attempt to "normalize" the filename in the following ways:

  • If the filename is empty, the class assumes that it's supposed to be myapp.xml and located in the same folder as the executable.
  • If the filename is just a path, the class assumes that it's supposed to be myapp.xml and verifies that the path you specified exists. If it doesn't exist, it sets the path to the path of the executable file.
  • If the filename is a path with just an extension, the class will set the filename to the app's name.

In the end, an acceptable filename should always be the result. The file does not have to exist, but the path must.

After the profile is loaded, you can access the data. If you attempt to retrieve a value whose section/key does not yet exist, that section/key/value is added to the list of values maintained within CProfile. If you try to set a section/key/value that doesn't exist, it will be automatically created and added to the list.

By default, CProfile will automatically save its data when it goes out of scope. If you don't want this functionality, simply include this line anytime within the current scope.

CProfile::SetAutoSave(false);

The class will not save until either you explicitly call the Save() function, or the CProfile object goes out of scope (and auto-save is turned on).

Getting and Setting Values

By default, if you try to get or set a value for a key that doesn't exist, CProfile will automatically create the key in the list. This duplicates the functionality of the Get/SetPrivateProfileString API for INI files. However, you can turn that functionality on and off for sets, gets, or both by calling the appropriate toggle function:

CProfile::SetAddOnFailedGets(bool)
CProfile::SetAddOnFailedSets(bool)

The default value is true for both toggles.

Debugging Functionality

If you want to make sure that your xml file loaded as expected, there are two built-in functions in CProfile that show the contents of the internal list - ShowContentsByRange() and ShowContentsBySection().

The "ByRange" function allows you to view all of the items within the specified index range. If you don't pass any range info at all, it assumes you want to see all of the items. Normally this shouldn't be a problem, but just in case you have a billion keys, you can specify a smaller range of items to view.

The "BySection" function shows all keys for the specified section. Again, this shouldn't normally be a problem, but if you have over 25 keys in a given section, you should consider writing an overload of this function that also accepts a non-optional set of range parameters.

Extra Stuff

I've also included some code that supports filename manipulation. It is provided only to support CProfile and discussion of that code is not within the context of this article. Feel free to talk amongst yourselves, but I won't be fielding any questions about it.

Disclaimers and Warranties

So there it is - nothing fancy and definitely not hard to use or understand. I'm sure there's something in this code that someone won't like, so instead of complaining about it, be a programmer and change it to suit your needs. Good luck.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

John Simmons / outlaw programmer
Software Developer (Senior)
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.
 
My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
GeneralCan't compile on VS2008 on Windows 7 PinmemberSuper Garrison11-May-11 5:57 
QuestionPerformance ? PinmemberDefenestration1-Nov-07 12:51 
AnswerRe: Performance ? PinmvpJohn Simmons / outlaw programmer1-Nov-07 23:39 
GeneralAnother Reason to be Portable Pinmemberhstahl24-Jun-07 5:42 
QuestionVista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmemberMike O'Neill15-Feb-07 7:23 
I personally like the paradigm of initialization by a Setup.ini or Setup.xml, for the same reasons expressed in this article. Moreover, with xml/ini files, any user with Notepad can easily modify the initialization, without resorting to a frustrating experience with Regedit, and without requiring the programmer to write an extensive interface to each and every setup parameter.
 
Under Vista, however, for standard users, the Vista UAC security model locks down directories like C:/Program Files etc. In other words, programs are not supposed to create/modify files like "C:\Program Files\<application>\Setup.xml" (or Setup.ini).
 
For continued support of legacy applications, Microsoft implemented the idea of "UAC virtualization", where files are not stored where the program thinks they're stored. See, for example, A Closer Look at Windows Vista, Part I: Security Changes[^].
 
Microsoft has warned developers that we should not depend on the existence of UAC virtualization in future releases of Windows, and that we should start to "fit in" to their preferred model of initialization (i.e., the registry).
 
For those of us who truly deplore the over-use of the registry, what should we do in the future?
 
Mike
AnswerRe: Vista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmvpJohn Simmons / outlaw programmer15-Feb-07 23:46 
GeneralRe: Vista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmemberMike O'Neill16-Feb-07 7:58 
AnswerRe: Vista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmvpJohn Simmons / outlaw programmer15-Feb-07 23:52 
AnswerRe: Vista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmemberDrew Stainton16-Feb-07 5:53 
AnswerRe: Vista UAC: What's the Future For XML-style (and ini-style) Initialization? PinmemberJohn Crenshaw20-Apr-07 11:43 
QuestionWhy not use xml attributes? PinmemberWong Shao Voon6-Feb-07 14:34 
AnswerRe: Why not use xml attributes? PinmvpJohn Simmons / outlaw programmer6-Feb-07 23:10 
GeneralReally Nice PinmvpRama Krishna Vavilala27-Jan-07 14:28 
QuestionXML now? PinmemberJoergen Sigvardsson27-Jan-07 5:25 
AnswerRe: XML now? PinmvpJohn Simmons / outlaw programmer27-Jan-07 5:46 
GeneralRe: XML now? PinmemberJoergen Sigvardsson27-Jan-07 6:59 
GeneralRe: XML now? PinmvpJohn Simmons / outlaw programmer27-Jan-07 7:31 
GeneralRe: XML now? PinmemberMike_V27-Jan-07 9:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 27 Jan 2007
Article Copyright 2007 by John Simmons / outlaw programmer
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid