Problem Reading Ini File Using GetPrivateProfileStringKey()

  • Thread starter Thread starter Phillip Galey
  • Start date Start date
P

Phillip Galey

With the following VB.NET code,

----------------------------------------------------------------------------
-----------------------------------------
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String)
As Long

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As
String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As Integer, ByVal lpDefault As String, ByVal lpReturnedString As
String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Sub DoIt()
Dim strData As String = Space(255)

WritePrivateProfileString(Application.ProductName, "Datum1", "NewInfo",
"MyInfo.ini")
GetPrivateProfileStringKey(Application.ProductName, "Datum1",
"DefaultInfo", strData, 255, "MyInfo.ini")
MsgBox (strData)
End Sub
----------------------------------------------------------------------------
-----------------------------------------

The WritePrivateProfileString line works, successfully saving the string
"Datum1=NewInfo" in the MyInfo.ini file under [Application.ProductName].
However, the next line fails to retrieve "NewInfo" without generating an
error, resulting in the MsgBox displaying "DefaultInfo". What am I doing
wrong in my implementation of GetPrivateProfileStringKey? Thanks.
 
Phillip Galey said:
With the following VB.NET code,

-------------------------------------------------------------------------- --
-----------------------------------------
Private Declare Function WritePrivateProfileString Lib "kernel32"
Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As
String, ByVal lpKeyName As String, ByVal lpString As String, ByVal
lpFileName As String) As Long

[...]

The WritePrivateProfileString line works, successfully saving the
string "Datum1=NewInfo" in the MyInfo.ini file under
[Application.ProductName]. However, the next line fails to retrieve
"NewInfo" without generating an error, resulting in the MsgBox
displaying "DefaultInfo". What am I doing wrong in my implementation
of GetPrivateProfileStringKey? Thanks.

http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconIntegerDataTypes.asp
http://msdn.microsoft.com/library/en-us/vbcon/html/vbconWindowsAPIChangesInVisualBasic70.asp
http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconCallingWindowsAPIs.asp
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconconsumingunmanageddllfunctions.asp
 
* "Phillip Galey said:
With the following VB.NET code,

----------------------------------------------------------------------------
-----------------------------------------
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String)
As Long

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As
String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As Integer, ByVal lpDefault As String, ByVal lpReturnedString As
String, ByVal nSize As Long, ByVal lpFileName As String) As Long

The declares are wrong -- 'Long' is now a 64 bit datatype. You will
have to use Int32/Integer instead. It's better to declare the functions
as 'Auto' and remove the alias.

Working sample:

<http://www.mentalis.org/soft/class.qpx?id=6>
 
With the following VB.NET code,

Corrected...
---------------------------------------------------------------------
Private Declare Auto Function WritePrivateProfileString Lib "kernel32" _
(ByVal lpApplication As String, _
ByVal lpKeyName As String, _
ByVal lpString As String, _
ByVal lpFileName As String) As Integer

Private Delcare Auto Function GetPrivateProfileString Lib "kernel32" _
(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 Sub DoIt()
Dim strData As New System.Text.StringBuilder(255)

WritePrivateProfileString(Application.ProductName, "Datum1", _
"NewInfo", "MyInfo.ini")

GetPrivateProfileString(Application.ProductName, "Datum1", _
"DefaultInfo", strData, strData.Capacity, "MyInfo.ini")

MsgBox (strData.ToString())
End Sub
---------------------------------------------------------------------
The WritePrivateProfileString line works, successfully saving the string
"Datum1=NewInfo" in the MyInfo.ini file under [Application.ProductName].
However, the next line fails to retrieve "NewInfo" without generating an
error, resulting in the MsgBox displaying "DefaultInfo". What am I doing
wrong in my implementation of GetPrivateProfileStringKey? Thanks.

Well, mostly the problem is that Long values in VB.NET are 64-bit,
unlike in VB.CLASSIC where they were 32-bit. In VB.NET - you should use
Integer.

Another problem - though not one that would cause errors - is actually
aliasing to a specific version of GetPrivateProfileString. You
shouldn't do that. You should, in most cases, drop the alias and use
Auto and let the runtime determine which version of the function to
call. This saves you a lot of unnecessary string conversions on NT
based systems.

Also, using strings for writable buffers is not a good idea. It works,
in VB.NET because the VB.NET marshaller does some extra work (which can
result in performance issues as well), but it also violates the
immutability of System.String. It is better, IMHO, to use
System.Text.StringBuilder for writable buffers. It will also make it
easier on you if you have to read/write any C# code, because in C#
passing a string in this case will not work. You won't get an error,
but the value won't change.
 
Back
Top