1

我正在使用VB.NETInstallShield中的自定义操作在安装期间更新某些属性。

只要我不尝试在属性中读取或写入超过 21 个字符,一切正常,在这种情况下它会崩溃。

为了清楚起见,如果我通过 IS 将这个字符串“123456789112345678921”输入到属性中,然后尝试从 VB.NET 读取它,一切正常。如果我添加另一个字符并阅读它,它会崩溃。写作是相似的——如果我写(来自VB.NET)上面的第一个字符串就可以了。如果我添加另一个字符,它会失败。

我怀疑我的 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

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

4

2 回答 2

2

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

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

于 2014-08-20T22:35:15.123 回答
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
于 2014-09-12T12:55:32.383 回答