只能从VB.NET读取/写入21个字符到InstallShield属性

时间:2014-08-20 13:39:45

标签: installer windows-installer installshield custom-action dtf

我在 InstallShield 中使用 VB.NET 自定义操作来在安装过程中更新一些属性。

只要我不尝试在属性中读取或写入超过21个字符,所有内容都有效,在这种情况下它会崩溃。

请注意,如果我输入此字符串" 123456789112345678921"通过IS进入属性,然后尝试从VB.NET中读取它,一切正常。如果我添加另一个字符并读取它,它会崩溃。 写作是类似的 - 如果我写(从VB.NET)上面的第一个字符串工作。如果我添加另一个char则失败。

我怀疑我错误地定义了MsiSetProperty和MsiGetProperty:

<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

这就是我访问字段的方式:

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

关于发生了什么的任何想法?

2 个答案:

答案 0 :(得分:2)

尝试使用 DTF 而不是dll导入。 DTF是部署工具基础 - 一组丰富的.NET程序集类,用于处理Windows Installer和自定义操作的所有方面。您可以避免处理所有COM或Win32 clunk,并且只能使用.NET类进行编写。

我猜你的实际问题与VB.NET如何导入dll文件的技术细节(可能是一些缓冲区大小问题)有关,但如果DTF解决了这个问题我就不会花费任何时间。

答案 1 :(得分:0)

问题在于我如何阅读该物业。您必须为传入数据预分配空间。显然没有在StringBuilder中指定空间,它只分配足够的21个字符。

我原来的(糟糕的)阅读方法是:

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

有效的是(请注意StringBuilder中的空格预分配)。我默认为256,但您可以输入您认为必要的任何值:

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