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





5.00/5 (7 votes)
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