如何在 NSIS 3.03 Unicode 中以字节为单位计算字符串长度

How to count string length in bytes in NSIS 3.03 Unicode

在将我们的 NSIS 设置从 2.46 Unicode 移植到 3.03 Unicode 时,我遇到了一个问题,该函数通过使用系统插件解决了 NSIS 中的最大字符串长度问题:

  System::Alloc 8096
  Exch 

  IntOp   + 0

  ${For} $iLoopIndex1 1 $stackSize
    ${stack::dll_read} "$stacktext" "$iLoopIndex1" $TmpVal $stackReturn
    StrLen  "$TmpVal"
    System::Call "*(&t $\"$TmpVal$\")"
    IntOp   + 
  ${Next}

  System::Call "user32::SetWindowText(i $CstPage.InfoExt.Text, i r1) i .s"
  Pop $TmpVal

  System::Free 

该功能还使用我们移植的支持 Unicode 的堆栈插件。

StrLen 返回字符串中的字符数,然后用于将字符串添加到缓冲区。对于 Unicode 构建,一个字符填充两个字节,这会破坏缓冲区中的文本。

我通过将 StrLen 的结果加倍解决了这个问题。

现在的问题是:

  1. 使用哪个函数来确定字符串的字节长度?
  2. NSIS 使用什么内部 Unicode 编码?
  3. 加倍长度是否安全,NSIS 使用固定宽度的 Unicode 编码吗?

NSIS Unicode 安装程序使用 UTF-16LE 字符串,就像 Windows 一样。 UTF-16LE 在字符(代理对等)方面的宽度不是固定的,但是将 StrLen.

的 return 值加倍是安全的

一个常见的"string size in bytes"习语是这样的:

StrLen  ""
IntOp   + 1 ; Add [=10=] terminator
!if "${NSIS_CHAR_SIZE}" > 1
    IntOp   * ${NSIS_CHAR_SIZE}
!endif
DetailPrint " is  bytes"

NSIS_CHAR_SIZE是一个字符编码单元的大小; 1 个在 ANSI 安装程序中,2 个在 Unicode 安装程序中。