INI-Library

    • VB.NET

    Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von BiedermannS.

      Hier mal eine .NET-Lösung zum Arbeiten mit INI-Dateien, ohne die WinAPI.

      INI-LIB:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Ini
      2. Public Delegate Function ProcessLine(ByVal input As String, ByVal section As String) As KeyValuePair(Of String, String)
      3. Public Delegate Function WriteLine(ByVal input As KeyValuePair(Of String, String), ByVal section As String) As String
      4. Public Shared Function DefaultProcessLine(ByVal input As String, ByVal section As String) As KeyValuePair(Of String, String)
      5. Dim tmp As String() = input.Split({"="c}, 2, StringSplitOptions.RemoveEmptyEntries)
      6. If tmp.Length > 1 Then
      7. Return New KeyValuePair(Of String, String)(tmp(0), tmp(1))
      8. Else
      9. Return New KeyValuePair(Of String, String)(tmp(0), "")
      10. End If
      11. End Function
      12. Public Shared Function DefaultWriteLine(ByVal input As KeyValuePair(Of String, String), ByVal section As String) As String
      13. Return String.Format("{0}={1}", input.Key, input.Value)
      14. End Function
      15. Private config As New Dictionary(Of String, Dictionary(Of String, String))
      16. Private _CurrentSection As String = String.Empty
      17. Public ReadOnly Property CurrentSection As String
      18. Get
      19. Return _CurrentSection
      20. End Get
      21. End Property
      22. Public Property ErrorLevel As eErrorLevel = eErrorLevel.none
      23. Public Function GetSections() As List(Of String)
      24. Return config.Keys.ToList
      25. End Function
      26. Public Function GetKeysFromSection() As List(Of String)
      27. If Not String.IsNullOrWhiteSpace(_CurrentSection) Then
      28. If config.Keys.Contains(_CurrentSection, comp) Then
      29. Return config(comp.LastResult).Keys.ToList()
      30. Else
      31. Return New List(Of String)
      32. End If
      33. Else
      34. Throw New Exception("No section loaded!")
      35. End If
      36. End Function
      37. Public Function GetKeys(ByVal SectionName As String) As List(Of String)
      38. Dim tmp As String = _CurrentSection
      39. Dim retval As New List(Of String)
      40. Try
      41. _CurrentSection = SectionName
      42. retval = GetKeysFromSection()
      43. Catch ex As Exception
      44. Throw ex
      45. Finally
      46. _CurrentSection = tmp
      47. End Try
      48. Return retval
      49. End Function
      50. Public Function LoadSection(ByVal SectionName As String) As Boolean
      51. Dim tmp As String = comp.LastResult
      52. If config.Keys.Contains(SectionName, comp) Then
      53. _CurrentSection = comp.LastResult
      54. Return True
      55. Else
      56. comp.LastResult = tmp
      57. Return False
      58. End If
      59. End Function
      60. Public Sub WriteSection(ByVal SectionName As String, Optional ByVal Overwrite As Boolean = False)
      61. If config.Keys.Contains(SectionName, comp) Then
      62. _CurrentSection = comp.LastResult
      63. If Overwrite Then
      64. config.Remove(_CurrentSection)
      65. config.Add(_CurrentSection, New Dictionary(Of String, String))
      66. End If
      67. Else
      68. _CurrentSection = SectionName
      69. config.Add(_CurrentSection, New Dictionary(Of String, String))
      70. End If
      71. End Sub
      72. Public Sub WriteValueToSection(ByVal Key As String, ByVal Value As String)
      73. If Not String.IsNullOrWhiteSpace(_CurrentSection) Then
      74. If config.Keys.Contains(_CurrentSection, comp) Then
      75. _CurrentSection = comp.LastResult
      76. If config(_CurrentSection).Keys.Contains(Key, comp) Then
      77. config(_CurrentSection)(comp.LastResult) = Value
      78. Else
      79. config(_CurrentSection).Add(comp.LastResult, Value)
      80. End If
      81. Else
      82. config.Add(_CurrentSection, New Dictionary(Of String, String) From {{Key, Value}})
      83. End If
      84. Else
      85. Throw New Exception("No section loaded!")
      86. End If
      87. End Sub
      88. Public Function GetValueFromSection(ByVal Key As String) As String
      89. If Not String.IsNullOrWhiteSpace(_CurrentSection) Then
      90. config.Keys.Contains(_CurrentSection, comp)
      91. _CurrentSection = comp.LastResult
      92. config(_CurrentSection).Keys.Contains(Key, comp)
      93. Return config(_CurrentSection)(comp.LastResult)
      94. Else
      95. Throw New Exception("No section loaded!")
      96. End If
      97. End Function
      98. Public Shadows Function TryGetValueFromSection(ByVal Key As String, Optional ByVal DefaultValue As String = "") As String
      99. If Not String.IsNullOrWhiteSpace(_CurrentSection) Then
      100. If config.Keys.Contains(_CurrentSection, comp) Then
      101. _CurrentSection = comp.LastResult
      102. If config(_CurrentSection).Keys.Contains(Key, comp) Then
      103. Return config(_CurrentSection)(comp.LastResult)
      104. Else
      105. Select Case ErrorLevel
      106. Case Ini.eErrorLevel.exception
      107. Throw New Exception("Key not found in [" & _CurrentSection & "].")
      108. Case Ini.eErrorLevel.debug
      109. WriteValue(_CurrentSection, comp.LastResult, DefaultValue)
      110. Debug.Print("------------------------------------------------")
      111. Debug.Print("Key not found in [" & _CurrentSection & "].")
      112. Debug.Print("Created new Key " & Chr(34) & Key & Chr(34))
      113. Debug.Print("with Default Value " & Chr(34) & DefaultValue & Chr(34) & " instead.")
      114. Debug.Print("------------------------------------------------")
      115. Case Else
      116. WriteValue(_CurrentSection, comp.LastResult, DefaultValue)
      117. End Select
      118. Return DefaultValue
      119. End If
      120. Else
      121. Select Case ErrorLevel
      122. Case Ini.eErrorLevel.exception
      123. Throw New Exception("[" & _CurrentSection & "] not found.")
      124. Case Ini.eErrorLevel.debug
      125. WriteValue(_CurrentSection, Key, DefaultValue)
      126. Debug.Print("------------------------------------------------")
      127. Debug.Print("[" & _CurrentSection & "] not found.")
      128. Debug.Print("Created new _CurrentSection " & Chr(34) & _CurrentSection & Chr(34))
      129. Debug.Print("Created new Key " & Chr(34) & Key & Chr(34))
      130. Debug.Print("with Default Value " & Chr(34) & DefaultValue & Chr(34) & " instead.")
      131. Debug.Print("------------------------------------------------")
      132. Case Else
      133. WriteValue(_CurrentSection, Key, DefaultValue)
      134. End Select
      135. Return DefaultValue
      136. End If
      137. Else
      138. Throw New Exception("No section loaded!")
      139. End If
      140. End Function
      141. Private comp As New KeyComparer
      142. Private Class KeyComparer
      143. Implements IEqualityComparer(Of String)
      144. Public Property LastResult As String
      145. Public Shadows Function Equals(x As String, y As String) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of String).Equals
      146. If x.ToLower = y.ToLower Then
      147. LastResult = x
      148. Return True
      149. Else
      150. LastResult = y
      151. Return False
      152. End If
      153. End Function
      154. Public Function GetHashCode1(obj As String) As Integer Implements System.Collections.Generic.IEqualityComparer(Of String).GetHashCode
      155. Return obj.GetHashCode
      156. End Function
      157. End Class
      158. Public Sub WriteValue(ByVal SectionName As String, ByVal Key As String, ByVal Value As String)
      159. Dim tmp As String = _CurrentSection
      160. Try
      161. _CurrentSection = SectionName
      162. WriteValueToSection(Key, Value)
      163. Catch ex As Exception
      164. Throw ex
      165. Finally
      166. _CurrentSection = tmp
      167. End Try
      168. End Sub
      169. Public Function GetValue(ByVal SectionName As String, ByVal Key As String) As String
      170. Dim tmp As String = _CurrentSection
      171. Dim retval As String = String.Empty
      172. Try
      173. _CurrentSection = SectionName
      174. retval = GetValueFromSection(Key)
      175. Catch ex As Exception
      176. Throw ex
      177. Finally
      178. _CurrentSection = tmp
      179. End Try
      180. Return retval
      181. End Function
      182. Public Enum eErrorLevel
      183. none
      184. debug
      185. exception
      186. End Enum
      187. Public Shadows Function TryGetValue(ByVal SectionName As String, ByVal Key As String, Optional ByVal DefaultValue As String = "") As String
      188. Dim tmp As String = _CurrentSection
      189. Dim retval As String = String.Empty
      190. Try
      191. _CurrentSection = SectionName
      192. retval = TryGetValueFromSection(Key, DefaultValue)
      193. Catch ex As Exception
      194. Throw ex
      195. Finally
      196. _CurrentSection = tmp
      197. End Try
      198. Return retval
      199. End Function
      200. Public Sub Load(ByVal path As String, ByVal processFunction As ProcessLine)
      201. Dim reg As New System.Text.RegularExpressions.Regex("\[.*\]")
      202. Using sw As New IO.StreamReader(path, System.Text.Encoding.Default)
      203. Dim tmp As String = String.Empty
      204. Dim SectionName As String = String.Empty
      205. Do Until sw.EndOfStream
      206. tmp = sw.ReadLine
      207. If tmp.StartsWith(";") Then
      208. Continue Do
      209. End If
      210. If reg.Matches(tmp).Count > 0 Then
      211. SectionName = tmp.Replace("[", "").Replace("]", "")
      212. ElseIf Not String.IsNullOrWhiteSpace(tmp) Then
      213. Dim result As KeyValuePair(Of String, String) = processFunction(tmp, SectionName)
      214. WriteValue(SectionName, result.Key, result.Value)
      215. End If
      216. Loop
      217. End Using
      218. End Sub
      219. Public Sub Load(ByVal path As String)
      220. Dim reg As New System.Text.RegularExpressions.Regex("\[.*\]")
      221. Using sw As New IO.StreamReader(path, System.Text.Encoding.Default)
      222. Dim tmp As String = String.Empty
      223. Dim SectionName As String = String.Empty
      224. Do Until sw.EndOfStream
      225. tmp = sw.ReadLine
      226. If tmp.StartsWith(";") Then
      227. Continue Do
      228. End If
      229. If reg.Matches(tmp).Count > 0 Then
      230. SectionName = tmp.Replace("[", "").Replace("]", "")
      231. ElseIf Not String.IsNullOrWhiteSpace(tmp) Then
      232. WriteValue(SectionName, tmp.Split("="c)(0), tmp.Split("="c)(1))
      233. End If
      234. Loop
      235. End Using
      236. End Sub
      237. Public Sub Save(ByVal path As String, ByVal processFunction As WriteLine)
      238. Using sw As New IO.StreamWriter(path, False, System.Text.Encoding.Default)
      239. For Each kv As KeyValuePair(Of String, Dictionary(Of String, String)) In config
      240. sw.WriteLine("[" & kv.Key & "]")
      241. For Each ikv As KeyValuePair(Of String, String) In kv.Value
      242. sw.WriteLine(processFunction(ikv, kv.Key))
      243. Next
      244. Next
      245. End Using
      246. End Sub
      247. Public Sub Save(ByVal path As String)
      248. Using sw As New IO.StreamWriter(path, False, System.Text.Encoding.Default)
      249. For Each kv As KeyValuePair(Of String, Dictionary(Of String, String)) In config
      250. sw.WriteLine("[" & kv.Key & "]")
      251. For Each ikv As KeyValuePair(Of String, String) In kv.Value
      252. sw.WriteLine(ikv.Key & "=" & ikv.Value)
      253. Next
      254. Next
      255. End Using
      256. End Sub
      257. Public Sub New()
      258. MyBase.New()
      259. End Sub
      260. Public Sub New(ByVal ErrorLevel As eErrorLevel)
      261. MyBase.New()
      262. Me.ErrorLevel = ErrorLevel
      263. End Sub
      264. Public Sub New(ByVal path As String, ByVal ErrorLevel As eErrorLevel)
      265. MyBase.New()
      266. Load(path)
      267. Me.ErrorLevel = ErrorLevel
      268. End Sub
      269. Public Sub New(ByVal path As String)
      270. MyBase.New()
      271. Load(path)
      272. End Sub
      273. End Class


      Beispiel:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Dim Settings As New ini
      2. 'Schreibt einen Wert in den Speicher, oder legt diesen neu an
      3. Settings.WriteValue("Section1", "MeinKey", "MeinValue")
      4. 'Liest einen Wert aus dem Speicher
      5. Dim MeinKey As String = Settings.GetValue("Section1", "MeinKey")
      6. MsgBox(MeinKey)
      7. 'Liest einen Wert aus dem Speicher,
      8. 'oder legt diesen mit einem definierten Wert (z.B.: "NewVal") an, falls noch nicht vorhanden
      9. Dim NewKey As String = Settings.TryGetValue("Section2", "NewKey", "NewVal")
      10. MsgBox(NewKey)
      11. 'Speichert das Ganze als INI-Datei
      12. Settings.Save("c:\test.ini")
      13. 'Lädt ein INI-Datei
      14. Settings.Load("c:\test.ini")
      15. 'Lädt ein INI-Datei
      16. Dim NewSettings As New ini("c:\test.ini")


      Mfg
      SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

      Weil einfach, einfach zu einfach ist! :D

      Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „BiedermannS“ ()

      Zwei Jahre nach dem ich den Code geschrieben habe, hatte ich das Vergnügen diesen wieder mal zu benutzen. Leider hat etwas an Funktionalität gefehlt, weshalb es jetzt auch ein Update gibt.

      Ich wollte die INI Files so gestalten, dass man bei gewissen Sektionen als Wert eine Nummer angeben kann. Alle darauf folgenden Werte sollten automatisch inkrementiert werden, wenn kein Wert übergeben wurde. Die Load- und die Save-Funktion nehmen nun optional einen Delegate an, mit dem man das Verhalten beim Einlesen steuern kann.

      Hier ein kleines Beispiel dazu:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Module Module1
      2. Dim ini As New IniLib.Ini
      3. ' Remember the last known number
      4. Dim lastNumber As Integer = 0
      5. Function processLine(ByVal input As String, ByVal section As String) As KeyValuePair(Of String, String)
      6. Dim tmp As String() = input.Split({"="c}, 2, StringSplitOptions.RemoveEmptyEntries)
      7. Select Case section.ToUpper()
      8. ' If we are currently in our "SPECIAL_SECTION"
      9. Case "SPECIAL_SECTION"
      10. Dim number As Integer
      11. ' Check if a number is provided
      12. If tmp.Length > 1 AndAlso Integer.TryParse(tmp(1), number) Then
      13. ' If yes, save the new last known number and return the values
      14. lastNumber = number
      15. Return New KeyValuePair(Of String, String)(tmp(0), tmp(1))
      16. Else
      17. ' If no, increment the new last known number and return the values
      18. lastNumber += 1
      19. Return New KeyValuePair(Of String, String)(tmp(0), lastNumber.ToString())
      20. End If
      21. ' In any other section, do the default parsing behaviour
      22. Case Else
      23. Return IniLib.Ini.DefaultProcessLine(input, section)
      24. End Select
      25. End Function
      26. Sub Main()
      27. ' Load the INI file with the provided function for processing
      28. ini.Load(".\test.ini", AddressOf processLine)
      29. End Sub
      30. End Module​
      SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

      Weil einfach, einfach zu einfach ist! :D