Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Writing Unicode Characters to an ASCII INI File (Yes, You Can!)

0.00/5 (No votes)
25 Oct 2016 2  
Writing /reading Unicode Characters and INI files in ASCII format

I was looking for a way to write Unicode characters to an INI file. I stumbled upon some solutions which were not satisfactory: they involved ANSI/UTF-8 files. So here is a workaround, including a small sample project.

Module INI
    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 Auto Function GetPrivateProfileString Lib "kernel32" (ByVal lpAppName As String, _
        ByVal lpKeyName As String, _
        ByVal lpDefault As String, _
        ByVal lpReturnedString As StringBuilder, _
        ByVal nSize As Integer, _
        ByVal lpFileName As String) As Integer

    Private Const EscapeChar As String = "#"

    Public Sub WritePrivateProfileStringUnicode(ApplicationName As String, KeyName As String, Value As String, FileName As String)
        Dim ValueUnicode As String = EncodeUnicodeString(Value)
        WritePrivateProfileString(ApplicationName, KeyName, ValueUnicode, FileName)
    End Sub

    Public Function GetPrivateProfileStringUnicode(ApplicationName As String, KeyName As String, FileName As String) As String
        Dim sb As New StringBuilder(500)
        GetPrivateProfileString(ApplicationName, KeyName, "", sb, sb.Capacity, FileName)
        Return DecodeUnicodeString(sb.ToString())
    End Function

    Public Function EncodeUnicodeString(value As String) As String
        'First escape the escape character
        Dim NewValue As String = Replace(value, EscapeChar, EscapeChar & Asc(EscapeChar) & EscapeChar)
        If IsUnicode(NewValue) Then
            'Value has unicode characters; we convert them to an integer value preceeded and followed by the escape character
            Dim i As Integer
            Dim ValueUnicode As String = ""
            For i = 1 To Len(NewValue)
                Dim strChar As String = Mid(NewValue, i, 1)
                If AscW(strChar) > 255 Or AscW(strChar) < 0 Then
                    strChar = EscapeChar & AscW(strChar) & EscapeChar
                End If
                ValueUnicode = ValueUnicode & strChar
            Next
            'Return encoded string
            Return ValueUnicode
        Else
            'Return unencoded string
            Return NewValue
        End If
    End Function

    Public Function DecodeUnicodeString(value As String) As String
        If InStr(Value, EscapeChar) = 0 Then
            'No #-character found, so there is nothing decode
            Return Value
        Else
            Dim i As Integer
            Dim Parts() As String = Split(Value, EscapeChar) 'Split value to array
            For i = 1 To UBound(Parts) Step 2         'If i is an odd number Parts(i) always contains a integer which should be converted back
                Parts(i) = Trim(ChrW(CInt(Parts(i))))
            Next
            Return Join(Parts, "")                    'Return the joined array Parts
        End If
    End Function

    Private Function IsUnicode(input As String) As Boolean
        Dim asciiBytesCount = Encoding.ASCII.GetByteCount(input)
        Dim unicodBytesCount = Encoding.UTF8.GetByteCount(input)
        Return asciiBytesCount <> unicodBytesCount
    End Function

End Module

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here