NSIS 使用 GetWinVer 获取系统版本号

2024-03-22 1044点热度 0人点赞 2条评论

以往在 NSIS 中我们使用 WinVer.nsh 头文件可以获取 Windows 系统版本号,自 NSIS 3.08 起官方新增了一个获取 Windows 版本号的命令 GetWinVer,通过它我们可以获取到详细的版本构建号,方便我们安装程序对系统支持的判断。

GetWinVer 参数:

GetWinVer user_var(output) Major|Minor|Build|ServicePack

先看一段示例脚本:

Name "GetWinVer"
OutFile "GetWinVer.exe"
ShowInstDetails Show
RequestExecutionLevel user

!include LogicLib.nsh

Section GetWinVer
  GetWinVer $0 Major
  GetWinVer $1 Minor
  GetWinVer $2 Build
  GetWinVer $3 ServicePack

  DetailPrint 'Windows Version: $0.$1.$2'

  ;ServicePack
  ${If} $3 != '0'
    DetailPrint 'ServicePack $3'
  ${EndIf}

  ;Version
  StrCpy $4 "$0.$1"
  ${Select} $4
    ${Case} '5.1'
      DetailPrint 'Windows XP'
    ${Case} '5.2'
      DetailPrint 'Windows XP x64 or Windows Server 2003'
    ${Case} '6.0'
      DetailPrint 'Windows Vista or Windows Server 2008'
    ${Case} '6.1'
      DetailPrint 'Windows 7 or Windows Server 2008R2'
    ${Case} '6.2'
      DetailPrint 'Windows 8 or Windows Server 2012'
    ${Case} '6.3'
      DetailPrint 'Windows 8.1 or Windows Server 2012R2'
    ${Case} '10.0'
      ${If} $2 < 22000
        DetailPrint 'Windows 10 or Windows Server 2016/2019/2022'
      ${Else}
        DetailPrint 'Windows 11'
      ${EndIf}
    ${CaseElse}
      DetailPrint 'Other Windows Version'
  ${EndSelect}

  ;Build
  ${If} $0 == '10'
  ${Select} $2
    ${Case} '10240'
      DetailPrint 'Windows10 1507/LTSB2015'
    ${Case} '10586'
      DetailPrint 'Windows10 1511'
    ${Case} '14393'
      DetailPrint 'Windows10 1607/LTSB2016 or Windows Server 2016'
    ${Case} '15063'
      DetailPrint 'Windows10 1703'
    ${Case} '16299'
      DetailPrint 'Windows10 1709'
    ${Case} '17134'
      DetailPrint 'Windows10 1803'
    ${Case} '17763'
      DetailPrint 'Windows10 1809/LTSC2019 or Windows Server 2019'
    ${Case} '18362'
      DetailPrint 'Windows10 1903'
    ${Case} '18363'
      DetailPrint 'Windows10 1909'
    ${Case} '19041'
      DetailPrint 'Windows10 2004'
    ${Case} '19042'
      DetailPrint 'Windows10 20H2'
    ${Case} '19043'
      DetailPrint 'Windows10 21H1'
    ${Case} '19044'
      DetailPrint 'Windows10 21H2 or LTSC2021'
    ${Case} '19045'
      DetailPrint 'Windows10 22H2'
    ${Case} '20348'
      DetailPrint 'Windows Server 2022'
    ${Case} '22000'
      DetailPrint 'Windows11 21H2'
    ${Case} '22621'
      DetailPrint 'Windows11 22H2'
    ${Case} '22631'
      DetailPrint 'Windows11 23H2'
    ${CaseElse}
      DetailPrint 'A New Windows10/11 Version'
  ${EndSelect}
  ${EndIf}
SectionEnd

编译以上脚本并运行,程序会打印出当前系统的:

  • 详细的版本号;
  • ServicePack(服务包号,如果有?);
  • Win10 以上系统我们还可以通过内部构建判断其年代版本。

再看两个示例:

1、某安装程序仅支持在 Windows7 SP1 系统安装,需要用到WordFunc.nsh头文件的${VersionCompare}函数,代码:

Name "TestWin7SP1"
OutFile "TestWin7SP1.exe"

!include LogicLib.nsh
!include WordFunc.nsh

Function .onInit
  GetWinVer $0 Major
  GetWinVer $1 Minor
  GetWinVer $2 Build
  ${VersionCompare} "$0.$1.$2" "6.1.7601" $3
  ${If} $3 > 1  ;此处表示当$3 < 6.1.7601 时。($3=0 版本相同;$3=1 版本1较高;$3=2 版本2较高)
    MessageBox MB_OK "当前系统不支持安装,仅支持 Win7SP1+"
    Abort
  ${EndIf}
FunctionEnd

Section -
SectionEnd

2、某安装程序需要在 Windows10 20H2 以上系统才能安装,代码:

Name "Test20H2"
OutFile "Test20H2.exe"

!include LogicLib.nsh

Function .onInit
  GetWinVer $0 Major
  GetWinVer $1 Build
  ${Unless} $0 >= 10        ;除非 Win10 或以上
  ${AndUnless} $1 >= 19042  ;并且 Build >= 19042
    MessageBox MB_OK "当前系统不支持安装,仅支持 Win10 20H2+"
    Abort
  ${EndUnless}
FunctionEnd

Section -
SectionEnd

以上只是简单演示,实际使用中如需复杂的系统判断,比如根据不同系统版本勾选不同组件区段、释放不同文件等,在熟悉各系统版本号的情况下,他比单纯使用 WinVer.nsh 头文件判断更详细!

附:当前主流 Windows 系统版本号

Windows XP               ;5.01.2600
Windows Vista            ;6.00.6000
Windows 7                ;6.01.7600
Windows 8                ;6.02.9200
Windows 8.1              ;6.03.9600
Windows 10               ;10.0.10240
Windows 11               ;10.0.22000

Windows Server 2003      ;5.02.3790
Windows Server 2008R2    ;6.01.7600
Windows Server 2012      ;6.02.9200
Windows Server 2012R2    ;6.03.9600
Windows Server 2016      ;10.0.14393
Windows Server 2019      ;10.0.20348
Windows Server 2022      ;10.0.17763

南陇居士

NLJS.SITE - 分享 · 记录

文章评论

  • joo seng

    IntOp 只能作整数运算。它会把小数部分给忽略掉。因此
    IntOp $3 6.1 * 10
    会得到$3=60 而不是61。

    2024-05-29