Read .ini file vb.net?

前端 未结 3 848
青春惊慌失措
青春惊慌失措 2021-01-07 10:00

I have one project with function to read .ini files. I can not display the contents of .ini file that I want to.

My code to read .ini file

Public Fun         


        
相关标签:
3条回答
  • 2021-01-07 10:35

    Example ini file:

    [MAIN]
    Setting_1=something
    

    a. Create a class clsINI

    Public Class clsIni
    ' 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)
        Else
            GetString = ""
        End If
    
    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
    

    b. Instantiate the class:

    Dim objIniFile As New clsIni(path_of_your_file)
    

    c. Get the setting:

    Dim x As String
    x = objIniFile.GetString("MAIN", "Setting_1", "")
    

    d. Update / Create a setting:

    objIniFile.WriteString("MAIN", "Setting_1", "new_setting")
    

    Edit:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim objIniFile As New clsIni("D:\WorldInfo.ini")
        Label1.Text = objIniFile.GetString("B_Empty_IndexList", "Count", "")
        Label2.Text = objIniFile.GetString("B_Use_IndexList", "Count", "")
    End Sub
    
    0 讨论(0)
  • 2021-01-07 10:40

    There is no point rolling your own method to do this. Use the Windows API method GetPrivateProfileString to do it:

    Imports System.Runtime.InteropServices
    Imports System.Text
    
    <DllImport("kernel32")>
    Private Shared Function GetPrivateProfileString(ByVal section As String, ByVal key As String, ByVal def As String, ByVal retVal As StringBuilder, ByVal size As Integer, ByVal filePath As String) As Integer
    End Function
    
    Public Function GetIniValue(section As String, key As String, filename As String, Optional defaultValue As String = "") As String
        Dim sb As New StringBuilder(500)
        If GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filename) > 0 Then
            Return sb.ToString
        Else
            Return defaultValue
        End If
    End Function
    
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Debug.WriteLine(GetIniValue("B_Empty_IndexList", "Count", My.Application.Info.DirectoryPath & "\WorldInfo.ini"))
        Debug.WriteLine(GetIniValue("B_Use_IndexList", "Count", My.Application.Info.DirectoryPath & "\WorldInfo.ini"))
    End Sub
    

    Note some background reading if using this approach: Could there be encoding-related problems when storing unicode strings in ini files?

    0 讨论(0)
  • 2021-01-07 10:48

    Those suggested Windows API have been deprecated for a long time now and they are really bad, you see on each GetPrivateProfile call you are reading and parsing the INI content all over again...

    As an alternative try using my MadMilkman.Ini library, like this:

    Imports MadMilkman.Ini
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim ini As New IniFile()
        ini.Load("D:\WorldInfo.ini")
    
        Label1.Text = ini.Sections("B_Empty_IndexList").Keys("Count").Value
        Label2.Text = ini.Sections("B_Use_IndecList").Keys("Count").Value
    End Sub
    

    You can download the library from here: https://github.com/MarioZ/MadMilkman.Ini

    EDIT
    I was asked to elaborate more the discussion that I had with IInspectable in the comments below.
    IInspectable: "Your solution doesn't appear to account for surrogate pairs."
    Mario Z: "I have no idea why you assume that library doesn't support Unicode, it does and its quite simple... just use the appropriate encoding."

    So here it goes, in short .NET's String represents an array of Chars and Char represents 16-bit character. When faced with a string that contains a 32-bit character it will use a so called "surrogate pair" (two characters that represent one). Now when working with this kind of string an issue that can happen for example is that we can make an invalid substring of that string if we cut it in the middle of that "surrogate pair". Also another issue that can happen is when working with the string indexer and not taking into account that a "surrogate pair" will consist of two indexed chars in that string.

    However that is all not the case with MadMilkman.Ini, the library directly manipulates only with a specific set of characters while the rest of the string is left as it is (string is a self-consistent type with a full Unicode support). The characters that are targeted and manipulated are [, ], =, etc.

    As an example here is a writing test sample:

    Dim textWithSurrogatePairs =
        "sample content " + Char.ConvertFromUtf32(Int32.Parse("22222", NumberStyles.HexNumber))
    
    Dim ini = New IniFile(
        New IniOptions() With {.Encoding = Encoding.Unicode})
    
    ini.Sections.Add(
        New IniSection(ini, "sample section",
            New IniKey(ini, "sample key", textWithSurrogatePairs)))
    
    ini.Save("sample file.ini")
    

    The following is the content of "textWithSurrogatePairs" variable:

    The following is the generated output "sample file.ini" file:

    Also here is reading test sample:

    Dim ini = New IniFile(
        New IniOptions() With {.Encoding = Encoding.Unicode})
    
    ini.Load("sample file.ini")
    
    Dim readValue = ini.Sections("sample section").Keys("sample key").Value
    

    The following is the "readValue" variable:

    So in short the .NET framework itself handles the surrogate pairs, the only thing that we need to be aware of is to use an appropriate Encoding (as shown above).
    Unfortunately this is something that IInspectable fails to realize and I failed to properly explain to him.

    0 讨论(0)
提交回复
热议问题