NSIS检测安装路径是否包含中文
侧边栏壁纸
  • 累计撰写 17 篇文章
  • 累计收到 1 条评论

NSIS检测安装路径是否包含中文

nsisfans
2022-01-15 / 0 评论 / 21 阅读 / 正在检测是否收录...

以 Unicode 字符串的方式进行判断 (与 NSIS 是 ANSI/Unicode 无关),但建议 Unicode 版本优先使用此函数。


Name "Path"
OutFile "Path.exe"

InstallDir "$PROGRAMFILES\Internet Explorer"

ShowInstDetails show
InstallColors /windows
XPStyle on

Page directory
Page instfiles

Section "Install"

SectionEnd

#
# 以 Unicode 字符串的方式进行判断 (与 NSIS 是 ANSI/Unicode 无关)
# 但建议 Unicode 版本优先使用此函数。
#
Function PathIsDBCS_W
    Exch $R0
    Push $R1
    Push $R2
    Push $R3
    System::Call "*(&w${NSIS_MAX_STRLEN}R0)p.R1"
    StrCpy $R0 0
    StrCpy $R2 $R1
lbl_loop:
    # Unicode 版取 2 个字节长度的字符,字符串遇到 0 字符表示结束了。
    System::Call "*$R2(&i2.R3)"
    IntCmp $R3 0 lbl_done
    # Unicode 字符直接判断字符值,大于 128 的我们就视为非英文字符。
    IntCmp $R3 128 0 lbl_skip
    IntOp $R0 $R0 !
    Goto lbl_done
lbl_skip:
    # 如果用 NSIS 3.x 这里可以用 IntPtrOp 代替。
    IntOp $R2 $R2 + 2
    Goto lbl_loop
lbl_done:
    System::Free $R1
    Pop  $R3
    Pop  $R2
    Pop  $R1
    Exch $R0
FunctionEnd

#
# 以 ANSI 字符串的方式进行判断 (与 NSIS 是 ANSI/Unicode 无关)
# 但建议 ANSI 版本优先使用此函数。
#
Function PathIsDBCS_A
    Exch $R0
    Push $R1
    Push $R2
    Push $R3
    Push $R4
    System::Call "*(&m${NSIS_MAX_STRLEN}R0)p.R1"
    StrCpy $R0 0
    StrCpy $R2 $R1
lbl_loop:
    # ANSI 版取 1 个字节长度的字符,字符串遇到 0 字符表示结束了。
    System::Call "*$R2(&i1.R3)"
    IntCmp $R3 0 lbl_done
    # ANSI 字符用 IsDBCSLeadByte 判断是否双字节字符的前导字节。
    System::Call "kernel32::IsDBCSLeadByte(iR3)i.R4"
    IntCmp $R4 0 lbl_skip
    IntOp $R0 $R0 !
    Goto lbl_done
lbl_skip:
    # 用 CharNextA 得到下一个字符的地址 (可正确处理双字节字符)。
    System::Call "user32::CharNextA(pR2)p.R2"
    Goto lbl_loop
lbl_done:
    System::Free $R1
    Pop  $R4
    Pop  $R3
    Pop  $R2
    Pop  $R1
    Exch $R0
FunctionEnd

#
# 当选择的安装路径变更时,路径为空或包含双字节字符 (不限于简体中文),都不允许继续。
# 路径为空时,NSIS 会自行判断。
#
# 此示例未判断是否包含空格。如有需要,请与示例一配合使用。
#
Function .onVerifyInstDir

    # 检查安装路径是否包含双字节字符 (不限于简体中文)。
    Push $INSTDIR
    # 这里也可以换成 PathIsDBCS_A 以测试效果。
    Call PathIsDBCS_W
    Pop $R0

    IntCmp $R0 0 lbl_done
    Abort
lbl_done:

FunctionEnd
0

评论 (0)

取消