Click here to Skip to main content
Click here to Skip to main content

IniFile Class using VB.NET

, 21 Jan 2004
Rate this:
Please Sign up or sign in to vote.
A .NET control to assist in the creation and manipualtion of *.ini files

Introduction

The February 2004 edition of MSDN magazine included some example code on how to build a custom class to save your winform settings to an *.ini file. This was a great idea, but the code presented was extremely limited, and basically only offered some Getval/Setval functions and a custom function to Get/Set your form settings quickly. Further hampering this code was its reliance on the Kernel32.dll *.ini file functions (WritePrivateProfileString, GetPrivateProfileString). I searched on Google for a better solution, but found nothing.

Many programmers choose to store their custom program settings in the registry, but this defeats the XCopy deployment paradigm of .NET programs. You should be able to copy settings along with the executable and go. Microsoft would have you store this information in an XML file, but the fact is that many end users (and even many programmers) still prefer the simple to open/edit format of the venerable old *.ini file. But Microsoft left out any kind of native support for this storage solution in .NET.

I decided to write my own class to handle this function. I'm not sure why every reference to *.ini files begins and ends with accessing the Kernel32.dll. I suppose people think that this would make things faster, or perhaps more accurate or secure. But the fact is that *.ini files are ultimately text files, and there is no reason they can't be handled as such. Furthermore, I don't want to be limited by the Get/Set nature of the Kernel32.dll functions. Controls designed for .NET are feature rich in nature, and this one should be no different.

Aside from getting and setting key values, I want to able to add, remove and edit sections. I want to be able to comment/uncomment key values, or even entire sections with ease. I want to be able to move a key from section to section. I want to be able to sort my sections and keys for easy reading. I want an easy way to store my form settings. And just to top it off, let's add the ability to dump an *.ini file out to XML should I decide to take that route in the future. In short, it should be a fully featured, simple to use control. Oh, and it should be free.

Using the code

Download the attached source code, which contains both the class file, and demo project - an Ini File Editor (of course). The code for the class is heavily commented, and should be easy to understand. There is also a detailed help file included, produced by NDoc and the VB.DOC Visual Studio addin.

A simple example of the class file would look something like this:

Imports IniFile
Dim myIniFile As New IniFile("C:\Test.ini") 
    'Create an IniFile object and load the *.ini file
myIniFile.AddKey("MyKey","MyValue","MySection") 
    'Create a section, and add new key/value to it
myIniFile.Sort() 'Sort all the sections and keys
myIniFile.ToXML("C:\Test.xml") 'Save the file to XML
myIniFile.Save("C:\Test.ini") 'Save the file

Points of Interest

  • Add, Delete, Edit, Comment and UnComment Sections
  • Add, Delete, Edit, Comment, UnComment and Move Keys/Values
  • Save form settings easily
  • List all Sections
  • Dump to XML
  • Sort file

The IndexOf() and Sort() Conundrums

While speed is not of the essence in this class (I simply cannot imagine a scenario where an *.ini file is being referenced thousands of times a second, or put under any kind of heavy load situation), I did try to make things as simple and fast as possible.

My first draft of this class was scrapped completely. It was based on a single ArrayList - the contents of the file were read line-by-line into the ArrayList, and then had to meticulously examined and manipulated in order to perform the necessary functions. It worked, but the code was ugly, and every time I tried to add even the most simple feature, I found myself re-writing huge hunks of code, and introducing new bugs.

It was then that I remembered I was dealing with an object oriented based language, and I should re-think my approach. I tried to think like Microsoft. Ok, so we have an *.ini file, that's an object. That file is made up of sections, those are objects. And each section has keys/values. Those are objects too. Suddenly, this made a lot sense, and everything fell into place from there.

The main component, the IniFile, is an ArrayList. I chose this, because the ArrayList class has some powerful features that make life easy, such as Add(), RemoveAt(), and IndexOf(), as well as sorting and searching features. This made adding and manipulating sections easy. The Section object is also based on an ArrayList, since it too needs to deal with child objects, namely, the keys. And keys are simple classes, with simple name/value strings.

This posed an interesting problem for me. Consider the following example:

 Dim myAL As New ArrayList()
 myAL.Add("The")
 myAL.Add("quick")
 myAL.Add("brown")
 Dim Quick_Index = myAL.IndexOf("quick")

In the above code, Quick_Index would contain a value of 1, which is the index of the string object called "quick". Simple enough.

But now consider this - the main ArrayList of IniFile (called Sections in the source code) contains not strings, but other ArrayLists (Sections). How do I use IndexOf() when the object I'm attempting to locate isn't a string object? And can I still sort the ArrayList? This same problem continues in the Sections Object, as it also contains custom classes (keys), and not string objects.

The sorting problem was solved by creating a custom comparer. The custom comparer implements IComparer, and allows me to direct the code as to how to compare one section to another.

Public Class SectionComparer
 Implements IComparer
 Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer  
 Implements System.Collections.IComparer.Compare
   Dim s1 As String = LCase(x.Name)
   Dim s2 As String = LCase(y.Name)
   Return s1.CompareTo(s2)
   End Function
 End Class

As you can see above, the custom comparer takes the x and y objects (does x = y?) and tells the computer how to go about comparing them. Since my Section objects each have a name value, I instructed the Compare function to compare those names (in lower case, just to be safe) and returned the result of that comparison. Then in the Sort() Function, I specify which comparer to use:

 Dim mySC As SectionComparer = New SectionComparer
 Sections.Sort(mySC)

That leaves me with the IndexOf() problem. IndexOf() doesn't take a comparer object. So now what? Well, it turns out that IndexOf() uses the Equals() method of the objects it is comparing to determine if we have a match. When you are comparing custom classes however, .NET simply uses the default Equals() method, which is to say, it compares the memory address of the object. Since two objects will never share the same memory address, they will never be equal. The fix is to override the Equals() method of the class, and tell the computer how to compare equal values of our custom class, much in the same way that we did with the custom comparer. An excellent example of this is here.

The problem is, this still isn't working. Take a look at the commented code in the GetKeyIndex() function to give this a try. If you find an answer, please email me so that I can update the code, and this article.

A final note

This is the first release of this code. It needs lots of testing, and has lots of room for improvement. If you find any bugs, or have any suggestions for improvements, they are welcomed. Thanks, and I hope you find this code to be of value to you.

History

  • Initial release of source code and documentation.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Todd Davis
Systems Engineer Virtual RadioLogic
United States United States
Todd Davis has been working in web and application development for several years, using Silverlight, ASP.NET, VB.NET, C#, C++ and Javascript, as well as a great deal of work with SQL server and IIS.
 
He currently works for Virtual Radiologic in Eden Prairie, MN, however he is better known for his varied work in the open source community, especially the DotNetNuke project for which he provided several world-renowned training videos and modules. A huge advocate of open source and open knowledge sharing, everything on his website (www.SeaburyDesign.com) is always offered for free.
 
Whenever he is not actively coding at his laptop (a rarity to be sure), he can be found woodworking, walking with his wife and kids, or motoring along the back roads of MN on his Harley Davidson Fatboy.

Comments and Discussions

 
Bugerror fix ??? PinmemberMember 1048140421-Dec-13 21:49 
QuestionSorry Folks PinmemberTodd Davis29-Nov-11 2:52 
Question[My vote of 1] bad code Pinmemberjiftle28-Nov-11 22:54 
QuestionRead and write ini files in VB.Net PinmemberNasenbaaer5-Oct-11 3:49 
Questionsorted keys PinmemberNeochange26-Sep-11 21:20 
GeneralNothing is working! PinmemberFred Blom14-Mar-10 9:35 
Generalgood help - comments and blanks support Pinmembertony joseph david11-Jan-09 17:10 
GeneralRe: good help - comments and blanks support PinmemberTodd Davis12-Jan-09 2:46 
QuestionAssembling the class inside the exe file? PinmemberSPB_BR15-Dec-08 2:12 
QuestionHow to wrtie code for download viedo and store Pinmemberjangitisampath22-Sep-08 23:51 
GeneralAbsolute life saver Pinmemberbigbrownbeaver18-Jul-07 8:15 
General*.ini files begins and ends with accessing the Kernel32.dll Pinmemberscarecrow9003-Jul-07 7:17 
GeneralNew Code Pinmemberralphowens9-May-07 11:31 
GeneralRe: New Code PinmemberOb3r0n11-May-07 23:26 
GeneralThanks! PinmemberTabathaLewis10-Nov-06 3:22 
GeneralString Handling PinmemberRajMac1-Sep-06 22:44 
Questionhow do IniFile Class using VB.NET in POCKET ? Pinmemberyu jun qiang12-May-06 16:03 
General*An alternative to IniFile Class, also available in C# & as cross-platform* Pinmemberdaluu24-Mar-06 8:23 
QuestionProblems turning GetSections and GetKeys into an array. PinmemberFordGT903-Mar-06 7:39 
AnswerRe: Problems turning GetSections and GetKeys into an array. PinmemberTodd Davis3-Mar-06 10:27 
GeneralRe: Problems turning GetSections and GetKeys into an array. PinmemberFordGT90Concept3-Mar-06 10:31 
GeneralGetPrivateProfileString Pinmemberitsolutions23-Feb-06 1:30 
AnswerRe: GetPrivateProfileString Pinmemberscarecrow9003-Jul-07 7:22 
GeneralPoor coding style Pinmembercarlopagliei3-Aug-05 0:27 
General.net technologies PinsussAnonymous8-Jul-05 21:08 
GeneralThis code... PinmemberGeorge Hendrickson27-May-05 2:42 
GeneralRead the value of a key in a section PinmemberKnautzberg11-Mar-05 10:01 
GeneralRe: Read the value of a key in a section Pinmemberdarthatom16-Sep-05 10:06 
Generala simple DataBase Pinmemberkyta5-Mar-05 17:18 
GeneralRe: a simple DataBase PinmemberTodd Davis6-Mar-05 1:54 
GeneralKey value not set when saving form Pinmemberkuhnsmadhouse12-Oct-04 9:01 
GeneralRe: Key value not set when saving form PinsussAnonymous12-Oct-04 9:04 
GeneralRe: Key value not set when saving form PinmemberTom Sander31-Jan-05 9:41 
GeneralThanks! PinmemberMichael J. Collins28-Jan-04 4:08 
GeneralNice work, some problems Pinmemberhuuhaa23-Jan-04 1:47 
GeneralRe: Nice work, some problems PinmemberTodd Davis23-Jan-04 2:44 
GeneralRe: Nice work, some problems PinmemberIcharus19-Jul-04 17:04 
GeneralRe: Nice work, some problems PinmemberToshRa25-Sep-07 8:31 

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
Web02 | 2.8.141022.2 | Last Updated 22 Jan 2004
Article Copyright 2004 by Todd Davis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid