Microsoft has been trying to get developers to move away from INI files for quite some time, pithily suggesting using the Registry instead… despite the fact that it’s rarely a suitable replacement. Well, this “hint” persists with .NET, which proudly boasts absolutely no intrinsic support for INI files.
But, of course, there’s always a workaround.
In previous versions of Visual Basic, you’d access your INI file through the API. Well, in VB.NET, we can simply do the same. Admittedly, Microsoft would prefer us to run “safe,” “managed” code within the .NET Framework—it can then automatically handle resources for you and ensure a more error-free environment.
However, you can still access “unmanaged” code, such as functions within the Windows API and COM components, with great ease.
In fact, here I’ve developed a class to encapsulate the functionality of some of those older INI file API functions. The fact that they’re wrapped up in a class also means that, should you ever implement another method of handling such settings, you can simply edit your code while the interfaces remain the same.
Anyway, enough talk—here’s my class code:
Public Class IniFile ' API functions Private Declare Ansi Function GetPrivateProfileString _ Lib "kernel32.dll" Alias "GetPrivateProfileStringA" _ (ByVal lpApplicationName As String, _ ByVal lpKeyName As String, ByVal lpDefault As String, _ ByVal lpReturnedString As System.Text.StringBuilder, _ ByVal nSize As Integer, ByVal lpFileName As String) _ As Integer Private Declare Ansi Function WritePrivateProfileString _ Lib "kernel32.dll" Alias "WritePrivateProfileStringA" _ (ByVal lpApplicationName As String, _ ByVal lpKeyName As String, ByVal lpString As String, _ ByVal lpFileName As String) As Integer Private Declare Ansi Function GetPrivateProfileInt _ Lib "kernel32.dll" Alias "GetPrivateProfileIntA" _ (ByVal lpApplicationName As String, _ ByVal lpKeyName As String, ByVal nDefault As Integer, _ ByVal lpFileName As String) As Integer Private Declare Ansi Function FlushPrivateProfileString _ Lib "kernel32.dll" Alias "WritePrivateProfileStringA" _ (ByVal lpApplicationName As Integer, _ ByVal lpKeyName As Integer, ByVal lpString As Integer, _ ByVal lpFileName As String) As Integer Dim strFilename As String ' Constructor, accepting a filename Public Sub New(ByVal Filename As String) strFilename = Filename End Sub ' Read-only filename property ReadOnly Property FileName() As String Get Return strFilename End Get End Property Public Function GetString(ByVal Section As String, _ ByVal Key As String, ByVal [Default] As String) As String ' Returns a string from your INI file Dim intCharCount As Integer Dim objResult As New System.Text.StringBuilder(256) intCharCount = GetPrivateProfileString(Section, Key, _ [Default], objResult, objResult.Capacity, strFilename) If intCharCount > 0 Then GetString = _ Left(objResult.ToString, intCharCount) End Function Public Function GetInteger(ByVal Section As String, _ ByVal Key As String, ByVal [Default] As Integer) As Integer ' Returns an integer from your INI file Return GetPrivateProfileInt(Section, Key, _ [Default], strFilename) End Function Public Function GetBoolean(ByVal Section As String, _ ByVal Key As String, ByVal [Default] As Boolean) As Boolean ' Returns a boolean from your INI file Return (GetPrivateProfileInt(Section, Key, _ CInt([Default]), strFilename) = 1) End Function Public Sub WriteString(ByVal Section As String, _ ByVal Key As String, ByVal Value As String) ' Writes a string to your INI file WritePrivateProfileString(Section, Key, Value, strFilename) Flush() End Sub Public Sub WriteInteger(ByVal Section As String, _ ByVal Key As String, ByVal Value As Integer) ' Writes an integer to your INI file WriteString(Section, Key, CStr(Value)) Flush() End Sub Public Sub WriteBoolean(ByVal Section As String, _ ByVal Key As String, ByVal Value As Boolean) ' Writes a boolean to your INI file WriteString(Section, Key, CStr(CInt(Value))) Flush() End Sub Private Sub Flush() ' Stores all the cached changes to your INI file FlushPrivateProfileString(0, 0, 0, strFilename) End Sub End Class
After you’ve added this class code to your application, here’s how you may want to use it:
Dim objIniFile As New IniFile("c:data.ini") objIniFile.WriteString("Settings", "ClockTime", "12:59") Dim strData As String = _ objIniFile.GetString("Settings", "ClockTime", "(none)")
Top Tip: As I mentioned earlier, Microsoft doesn’t really like people using INI files. It doesn’t fit in with its vision. IT would prefer developers use code like this only as a stop-gap measure while upgrading existing systems, then move onto an XML-based method of storing settings. Visit www.gotdotnet.com/userfiles/demeester/XMLINIFile.zip for an INI file replacement, using XML. But, of course, it’s completely up to you.
About the Author
Karl Moore (MCSD, MVP) is an experience author living in Yorkshire, England. He is the author of numerous technology books, including the new Ultimate VB .NET and ASP.NET Code Book (ISBN 1-59059-106-2, $49.99), plus regularly features at industry conferences and on BBC radio. Moore also runs his own creative consultancy, White Cliff Computing Ltd. Visit his official Web site at www.karlmoore.com.
# # #