INI-Bearbeitung mit API

Bearbeitung von INI-Dateien mit dem Win32-API

Obwohl Microsoft seit Jahren versucht, Entwickler von der Nutzung von INI-Dateien abzubringen und stattdessen die Registry zu benutzen, erfreut sich die Nutzung dieser sog. Konfigurationsdateien großer Beliebtheit.

Für (fast) jeden Bearbeitungsschritt stellt uns das Win32-API eine Funktion zur Verfügung:

Verfügbare API-Funktionen
Aufgabe API-Funktion
Sämtliche Sektions- bzw. Abschnittsnamen ermitteln GetPrivateProfileSectionNames
Einen kompletten Abschnitt „lesen“ GetPrivateProfileSection
Einen kompletten Abschnitt „schreiben“ WritePrivateProfileSection
Einen einzelnen Schlüsselwert „lesen“ GetPrivateProfileString
Einen einzelnen Schlüsselwert „schreiben“ WritePrivateProfileString
Einen einzelnen Schlüsselwert in WIN.INI „lesen“ GetProfileString
Einen einzelnen Schlüsselwert in WIN.INI „schreiben“ WriteProfileString

Das war die gute Nachricht.

Der Umgang mit diesen Funktionen stellt sich zum Teil nicht ganz so simpel dar. Zunächst benötigen wir natürlich wieder die modulglobalen Deklarationen dieser Funktionen. Hierzu sollte man ein eigenes Modul erstellen, um diese Zugriffe auf INI-Dateien zu kapseln. Fügen wir unserem VBA-Projekt also ein neues Modul hinzu und nennen dieses Modul modINI.

Im Kopfbereich unseres neuen Moduls werden die „Declares“ hinterlegt. Auf die beiden Funktionen für den Zugriff auf die WIN.INI wurde hier verzichtet, da wir nur auf unsere eigene INI-Datei zugreifen wollen. Diese „Declares“ sind hier nun „Private“ deklariert, was bedeutet, dass außerhalb dieses Moduls nichts und niemand direkt darauf zugreifen kann. Für den indirekten Zugriff werden wir entsprechende „Wrapper“-Funktionen erstellen. Dabei handelt es sich um Funktionen, die diese API-Funktionen kapseln und „von außen“ recht einfach genutzt werden können.

Beispiel:

Option Explicit
 
Private Declare Function GetPrivateProfileSectionNames Lib "kernel32" Alias _
                        "GetPrivateProfileSectionNamesA" _
                        (ByVal lpszReturnBuffer As String, _
                         ByVal nSize As Long, _
                         ByVal lpFileName As String) As Long
 
Private Declare Function WritePrivateProfileSection Lib "kernel32" Alias _
                        "WritePrivateProfileSectionA" _
                        (ByVal lpAppName As String, _
                         ByVal lpString As String, _
                         ByVal lpFileName As String) As Long
 
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias _
                        "WritePrivateProfileStringA" _
                        (ByVal lpApplicationName As String, _
                         ByVal lpKeyName As Any, _
                         ByVal lpString As Any, _
                         ByVal lpFileName As String) As Long
 
Private Declare Function GetPrivateProfileSection Lib "kernel32" Alias _
                        "GetPrivateProfileSectionA" _
                        (ByVal lpAppName As String, _
                         ByVal lpReturnedString As String, _
                         ByVal nSize As Long, _
                         ByVal lpFileName As String) As Long
 
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias _
                        "GetPrivateProfileStringA" _
                        (ByVal lpApplicationName As String, _
                         ByVal lpKeyName As Any, _
                         ByVal lpDefault As String, _
                         ByVal lpReturnedString As String, _
                         ByVal nSize As Long, _
                         ByVal lpFileName As String) As Long

Grundsätzliches zur Nutzung dieser Win32-Funktionen

  • Jede Funktion erwartet als letztes Argument (lpFileName) einen gültigen Pfad zu einer INI-Datei.
  • Existiert die INI-Datei, wird sie genutzt. Falls nicht, wird sie automatisch angelegt.
  • Es gibt Funktionen, um Sektionen zu schreiben – es gibt aber keine zum Löschen!
  • Wie (fast) alle anderen Win32-API Funktion erfolgt deren Nutzung sehr restriktiv hinsichtlich ihrer Sicherheit – es wird grundsätzlich nicht nachgefragt, bevor etwas geändert oder gelöscht wird.

Nachfolgend werden wir uns die notwendigen „Wrapper“-Funktionen erstellen.