I'm using VB.NET and a custom action from within InstallShield to update some properties during an install.
Everything works as long as I don't try to read or write more than 21 characters into the property, in which case it crashes.
Just to be clear, if I enter this string "123456789112345678921" into the property via IS, then try to read it from VB.NET, everything works. If I add another char and read that, it crashes. Writing is similar - if I write (from VB.NET) the first string above it works. If I add another char it fails.
My suspicion is that I have the MsiSetProperty and MsiGetProperty defined incorrectly:
<DllImport(MSI_LIB, EntryPoint:="MsiSetProperty", CharSet:=CharSet.Auto)> _
Public Shared Function MsiSetProperty(hInstall As IntPtr, name As String, value As String) As UInteger
End Function
<DllImport(MSI_LIB, EntryPoint:="MsiGetProperty", CharSet:=CharSet.Auto)> _
Private Shared Function MsiGetProperty_Core(hInstall As IntPtr, szName As String, <Out> szValueBuf As StringBuilder, ByRef pchValueBuf As Integer) As Integer
End Function
Public Shared Function MSIGetProperty(hMSI As IntPtr, PropertyName As String) As String
Try
Dim MSIProp As New StringBuilder()
Dim stringSize As Integer = 256
Dim value As Integer = MsiGetProperty_Core(hMSI, PropertyName, MSIProp, stringSize)
Return MSIProp.ToString()
Catch
Return "-1"
End Try
End Function
This is how i'm accessing the fields:
Public Property ReportServerURL As String
Get
Return MSIFunctions.MSIGetProperty(_msiHandle, "REPORTSERVERURL")
End Get
Set(value As String)
MSIFunctions.MsiSetProperty(_msiHandle, "REPORTSERVERURL", value)
End Set
End Property
Any ideas on what's going on?
Problem was with how I was reading the property. You MUST preallocate space for the incoming data. Apparently without specifying space in StringBuilder, it only allocates enough for 21 chars.
My original (bad) method for reading was this:
Public Shared Function MSIGetProperty(hMSI As IntPtr, PropertyName As String) As String
Try
Dim MSIProp As New StringBuilder()
Dim stringSize As Integer = 256
Dim value As Integer = MsiGetProperty_Core(hMSI, PropertyName, MSIProp, stringSize)
Return MSIProp.ToString()
Catch
Return "-1"
End Try
End Function
The one that works is this (note the preallocation of space in StringBuilder). I default to 256, but you can probably put in any value you think necessary:
Public Shared Function MSIGetProperty(hMSI As IntPtr, PropertyName As String) As String
Try
Dim stringSize As Integer = 256
Dim MSIProp As New StringBuilder(stringSize) 'MUST pre-allocate storage
Dim value As Integer = MsiGetProperty_Core(hMSI, PropertyName, MSIProp, stringSize)
Return MSIProp.ToString()
Catch
Return "-1"
End Try
End Function