使用NSIS更新%PATH%环境variables

我读到“长度超过$ {NSIS_MAX_STRLEN} (1024)的string将被截断/损坏”。

我如何安全地更新%PATH%环境variables

您可以使用特殊构建页面中的替代NSIS构建,如定义了NSIS_MAX_STRLEN=8192的大型字符串构建 ,并应该阻止您中断主机路径。

实际上,在桌面计算机上,1024字节似乎就够了,但是在安装了许多工具(如我的)的开发主机上,操作之后路径可能会中断,而8192字节的字符串从未扰乱我的机器。

要非常确定,可以在操作之前添加一个路径长度检查,并在尝试操作该路径之前路径接近NSIS_MAX_STRLEN常量的情况下,用消息中止安装程序。

真正的解决方案是编写一个自定义插件或直接使用系统插件调用Windows API,以避免NSIS缓冲区长度限制:

 !include LogicLib.nsh !include WinCore.nsh !ifndef NSIS_CHAR_SIZE !define NSIS_CHAR_SIZE 1 !endif Function RegAppendString System::Store S Pop $R0 ; append Pop $R1 ; separator Pop $R2 ; reg value Pop $R3 ; reg path Pop $R4 ; reg hkey System::Call 'ADVAPI32::RegCreateKey(i$R4,tR3,*i.r1)i.r0' ${If} $0 = 0 System::Call 'ADVAPI32::RegQueryValueEx(ir1,tR2,i0,*i.r2,i0,*i0r3)i.r0' ${If} $0 <> 0 StrCpy $2 ${REG_SZ} StrCpy $3 0 ${EndIf} StrLen $4 $R0 StrLen $5 $R1 IntOp $4 $4 + $5 IntOp $4 $4 + 1 ; For \0 !if ${NSIS_CHAR_SIZE} > 1 IntOp $4 $4 * ${NSIS_CHAR_SIZE} !endif IntOp $4 $4 + $3 System::Alloc $4 System::Call 'ADVAPI32::RegQueryValueEx(ir1,tR2,i0,i0,isr9,*ir4r4)i.r0' ${If} $0 = 0 ${OrIf} $0 = ${ERROR_FILE_NOT_FOUND} System::Call 'KERNEL32::lstrlen(t)(ir9)i.r0' ${If} $0 <> 0 System::Call 'KERNEL32::lstrcat(t)(ir9,tR1)' ${EndIf} System::Call 'KERNEL32::lstrcat(t)(ir9,tR0)' System::Call 'KERNEL32::lstrlen(t)(ir9)i.r0' IntOp $0 $0 + 1 !if ${NSIS_CHAR_SIZE} > 1 IntOp $0 $0 * ${NSIS_CHAR_SIZE} !endif System::Call 'ADVAPI32::RegSetValueEx(ir1,tR2,i0,ir2,ir9,ir0)i.r0' ${EndIf} System::Free $9 System::Call 'ADVAPI32::RegCloseKey(ir1)' ${EndIf} Push $0 System::Store L FunctionEnd Section Push ${HKEY_CURRENT_USER} Push "Environment" Push "Path" Push ";" Push "c:\whatever" Call RegAppendString Pop $0 DetailPrint RegAppendString:Error=$0 SectionEnd 

我已经写了NSIS 3.0例子来处理长于限制的情况,而不需要安装任何东西。 在这里回答了这个问题: 在Window 7中用NSIS设置环境变量