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?
Try using DTF instead of the dll imports. DTF is Deployment Tools Foundation - a rich set of .NET assembly classes for dealing with all aspects of Windows Installer and custom actions. You avoid having to deal with all COM or Win32 clunk, and can write using .NET classes only.
I guess your actual problem is related to a technical detail (maybe some buffer size issue) with regards to how VB.NET imports dll files, but I wouldn't spend any time on that if DTF solves the problem.
- forum.installsite.net
- Main Wix documentation
- DTF - Deployment Tools Foundation - .NET (quick overview towards the bottom of the answer)
- Read last section here
- Is source-code for Deployment Tools Foundation available?
- Deployment Tools Foundation (DTF) Managed Custom Actions
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