Visual Basic File Routines
WritePrivateProfileString: INI Files - The Basics
     
Posted:   Friday August 13, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6, and VB3, VB4-16 with appropriate declarations
Developed with:   VB6, Windows NT4
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

WritePrivateProfileString: INI Files - Saving Entire Sections
     
 Prerequisites
None.

All VB programmers need to persist application settings and data between sessions. Prior to Windows 95 the most popular ways were to save the data as a VB Type, or to write the data out line by line to a text file. The magic of the Windows 3x INI files eluded most until the Get/WriteProfileString and Get/WritePrivateProfileString APIs were discovered. 

Since releasing Windows 95, Microsoft has switched tactics and has consistently encouraged developers to save their application-persistent data to the registry. To make that even easier to adopt, they provided the VB Get/SaveSetting methods. But as the registry grows larger, and systems fail because of poorly-designed apps, the question being asked has become "Is the registry always the right place to store data?" Even MS says no; while they encourage application designers to use the registry for small data sets (i.e. window position, recent files), they agree that larger application-specific data should not be stored there (i.e. list content).

While the registry via API continues to offer more flexibility in the type of data that can be saved, the INI file still has its place in the developer's arsenal, especially as users - and especially   developers - grow increasingly concerned over an application's interference with the system registry, a critical and at times sensitive (aka temperamental) part of the operating system. It is actually becoming common place for users to refuse to use software from third-parties that directly write to the registry. And the INI file continues to hold the top place as the mechanism of choice with developers sincerely concerned with their users wishes and their systems.

Windows actually provides a number of "Profile" APIs available to the developer:

API
File Description
GetPrivateProfileInt user.ini retrieves an integer associated with a key in the specified section of the given initialization file.
GetPrivateProfileSection user.ini retrieves all of the keys and values for the specified section from an initialization file.
Windows 95: The specified profile section must not exceed 32K.
Windows NT/2000: The specified profile section has no size limit.
GetPrivateProfileSectionNames user.ini retrieves the names of all sections in an initialization file.
GetPrivateProfileString user.ini retrieves a string from the specified section in an initialization file
GetPrivateProfileStruct user.ini retrieves the data associated with the specified key in the given section of an initialization file. As it retrieves the data, the function calculates a checksum and compares it with the checksum calculated by the WritePrivateProfileStruct function when the data was added to the file.
GetProfileInt win.ini retrieves an integer from the specified key name in the given section of the WIN.INI file.
GetProfileSection win.ini retrieves all of the keys and values for the specified section of the WIN.INI file.
GetProfileString win.ini retrieves the string associated with the specified key in the given section of the WIN.INI file.
WritePrivateProfileSection user.ini replaces the keys and values under the specified section in an initialization file.
WritePrivateProfileString user.ini copies a string into the specified section of the specified initialization file.
WritePrivateProfileStruct copies data into the specified key in the given section of an initialization file. As it copies the data, the function calculates a checksum and appends it to the end of the data. The GetPrivateProfileStruct function uses the checksum to ensure the integrity of the data.
WriteProfileSection win.ini replaces the contents of the specified section in the WIN.INI file with the specified keys and values.
WriteProfileString win.ini copies a string into the specified section of the WIN.INI file.

References to "user.ini" indicate that the API is for use with application-specific files. The file can have any name, but it remains the custom is to name it the same as the application to facilitate easier locating should it need editing or removal. And historically, in Win3x days, Microsoft had encouraged saving application-specific ini files in the system's Windows directory. Common practice nowadays is to use the application's folder.

Despite the number of possible APIs available, most applications get away with using only two - GetPrivateProfileString and WritePrivateProfileString. Regardless, all the APIs share a commonality in the declaration of the APIs and the method of passing/receiving data using any given one.

This demo starts out by covering the basics - using GetPrivateProfileString and WritePrivateProfileString to read/write data to a private ini file. And long with saving and reading, we'll also cover deleting specific items as well as entire sections. In VBnet fashion, there is more commenting than code; you'll be pleasantly surprised how little code is really necessary to add this functionality to your apps.

Subsequent demos will build on the same BAS module, providing enhanced functionality. And while there now exists APIs to handle entire sections at a time (something introduced with Win9x), as a learning process those will be skipped in favour of using just the same two APIs to do everything we need.

 BAS Module Code
None.

 
 Form Code
On a form, add four command buttons (Command1 through Command4), and four text boxes (Text1 through Text4). Labels are optional; the code will title the buttons. Add the following code to the form:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private sIniFile  As String

Private Declare Function GetPrivateProfileString _
   Lib "kernel32" Alias "GetPrivateProfileStringA" _
  (ByVal lpSectionName As String, _
   ByVal lpKeyName As Any, _
   ByVal lpDefault As String, _
   ByVal lpbuffurnedString As String, _
   ByVal nBuffSize As Long, _
   ByVal lpFileName As String) As Long
   
Private Declare Function WritePrivateProfileString _
   Lib "kernel32" Alias "WritePrivateProfileStringA" _
  (ByVal lpSectionName As String, _
   ByVal lpKeyName As Any, _
   ByVal lpString As Any, _
   ByVal lpFileName As String) As Long



Private Sub Form_Load()

  'setup
   Text1.Text = "VBnet Demo"
   Text2.Text = "URL1"
   Text3.Text = "http://vbnet.mvps.org/"
   
  'Text4 is used only to display the 
  'contents of the raw file. Editing 
  'the contents of this text box will 
  'have no effect on the demo and will. 
  'Ensure Text4 is set to Multiline.
   Text4.Text = ""
   
   With Command1
      .Caption = "Save Key and Value under Section"
      .Width = 2700
   End With
   
   With Command2
      .Caption = "Save Value of Key under Section"
      .Width = 2700
   End With
   
   With Command3
      .Caption = "Delete Key and Value from INI"
      .Width = 2700
   End With
   
   With Command4
      .Caption = "Delete Entire Section from INI"
      .Width = 2700
   End With
   
  'this will be our test file
   sIniFile = App.Path & "\test.ini"
   
  'show the file contents (empty at first)
   Call LoadIniFile
   
 End Sub


Private Sub Command1_Click()

  'save the the value entered under 
  'the key in the specified section
   Dim sSection As String
   Dim sKeyName As String
   Dim sValue As String
   
   sSection = Text1.Text
   sKeyName = Text2.Text
   sValue = Text3.Text
   
   Call ProfileSaveItem(sSection, sKeyName, sValue, sIniFile)
   
  'refresh the raw file contents 
   LoadIniFile

End Sub


Private Sub Command2_Click()

  'load the value of the specified key 
  'located in sSection 
   Dim sSection As String
   Dim sKeyName As String
   Dim sResult As String
   
   sSection = Text1.Text
   sKeyName = Text2.Text
   Text3.Text = ""
   
   sResult = ProfileGetItem(sSection, _
                            sKeyName, _
                            "oops...data not in file!", _
                            sIniFile)
   
   Text3.Text = sResult
   
   LoadIniFile

End Sub


Private Sub Command3_Click()

  'delete the specified key (and its value)
  'from the specified section
   Dim sSection As String
   Dim sKeyName As String
   
   sSection = Text1.Text
   sKeyName = Text2.Text
   
   Call ProfileDeleteItem(sSection, sKeyName, sIniFile)
   
   LoadIniFile

End Sub


Private Sub Command4_Click()

  'delete the entire section specified
   Dim sSection As String
   
   sSection = Text1.Text
   
   Call ProfileDeleteSection(sSection, sIniFile)
   
   LoadIniFile

End Sub


Private Function ProfileGetItem(sSection As String, _
                                sKeyName As String, _
                                sDefValue As String, _
                                sIniFile As String) As String

  'retrieves a value from an ini file
  'corresponding to the section and
  'key name passed.
        
   Dim dwSize As Long
   Dim nBuffSize As Long
   Dim buff As String
  
  'Call the API with the parameters passed.
  'nBuffSize is the length of the string
  'in buff, including the terminating null.
  'If a default value was passed, and the
  'section or key name are not in the file,
  'that value is returned. If no default
  'value was passed (""), then dwSize
  'will = 0 if not found.
  '
  'pad a string large enough to hold the data
   buff = Space$(2048)
   nBuffSize = Len(buff)
   dwSize = GetPrivateProfileString(sSection, _
                                    sKeyName, _
                                    sDefValue, _
                                    buff, _
                                    nBuffSize, _
                                    sIniFile)
   
   If dwSize > 0 Then
      ProfileGetItem = Left$(buff, dwSize)
   End If
   
End Function


Private Sub ProfileSaveItem(sSection As String, _
                            sKeyName As String, _
                            sValue As String, _
                            sIniFile As String)

  'This function saves the passed value to the file,
  'under the section and key name specified.
  '
  'If the ini file does not exist, it is created.
  'If the section does not exist, it is created within the file.
  'If the key name does not exist, it is created under the section.
  'If the key name exists, it's value is replaced.
   
   Call WritePrivateProfileString(sSection, sKeyName, sValue, sIniFile)

End Sub


Private Sub ProfileDeleteItem(sSection As String, sKeyName As String, sIniFile As String)

  'this call will remove the keyname and its
  'corresponding value from the section sepcified
  'in sSection. This is accomplished by passing
  'vbNullString as the sValue parameter. For example,
  'assuming that an ini file had:
  ' [Colours]
  '  Colour1=Red
  '  Colour2=Blue
  '  Colour3=Green
  '
  'and this sub was called passing "Colour2"
  'as sKeyName, the resulting ini file
  'would contain:
  ' [Colours]
  '  Colour1=Red
  '  Colour3=Green
   
   Call WritePrivateProfileString(sSection, _
                                  sKeyName, _
                                  vbNullString, _
                                  sIniFile)

End Sub


Private Sub ProfileDeleteSection(sSection As String, sIniFile As String)

  'this call will remove the entire section
  'corresponding to sSection in the file.
  'This is accomplished by passing
  'vbNullString as both the sKeyName and
  'sValue parameters. For example, assuming 
  'that an ini file had:
  ' [Colours]
  '  Colour1=Red
  '  Colour2=Blue
  '  Colour3=Green
  '
  'and this sub was called passing "Colours"
  'as sSection, the entire Colours
  'section and all keys and values in 
  'the section would be deleted.
   
   Call WritePrivateProfileString(sSection, _
                                  vbNullString, _
                                  vbNullString, _
                                  sIniFile)

End Sub


Private Sub LoadIniFile()

   Dim hFile As Integer
   
   On Local Error Resume Next

  'obtain the next free file handle
   hFile = FreeFile

  'load the file
   Open sIniFile For Input As #hFile
      Text4.Text = Input$(LOF(hFile), hFile)
   Close #hFile
   
End Sub
 Comments
The form code is pretty self-explanatory. Each command button retrieves the data from the required textbox, and writes or reads as needed. After each call, Text4 is refilled with the current file contents.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter