1!ifndef _AddToPath_nsh 2!define _AddToPath_nsh 3 4######################## 5# Usage Example 6# 7#Section "Add to path" 8# Push $INSTDIR 9# Call AddToPath 10# 11# Push "LIB" 12# Push "c:\Mylibrary\lib" 13# Call AddToEnvVar 14# 15# ;likewise AddToPath could be 16# Push "PATH" 17# Push $INSTDIR 18# Call AddToEnvVar 19# 20#SectionEnd 21# 22## ... 23# 24#Section "uninstall" 25# # ... 26# Push $INSTDIR 27# Call un.RemoveFromPath 28# # ... 29# Push "LIB" 30# Push "c:\Mylibrary\lib" 31# Call un.RemoveFromEnvVar 32# 33# ;Likewise RemoveFromPath could be 34# Push "PATH" 35# Push $INSTDIR 36# Call un.RemoveFromEnvVar 37#SectionEnd 38########################### 39 40!verbose 3 41!include "WinMessages.NSH" 42!verbose 4 43 44!ifndef WriteEnvStr_RegKey 45 !ifdef ALL_USERS 46 !define WriteEnvStr_RegKey \ 47 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' 48 !else 49 !define WriteEnvStr_RegKey 'HKCU "Environment"' 50 !endif 51!endif 52 53; AddToPath - Adds the given dir to the search path. 54; Input - head of the stack 55; Note - Win9x systems requires reboot 56 57Function AddToPath 58 Exch $0 59 Push $1 60 Push $2 61 Push $3 62 63 # don't add if the path doesn't exist 64 IfFileExists "$0\*.*" "" AddToPath_done 65 66 ReadEnvStr $1 PATH 67 Push "$1;" 68 Push "$0;" 69 Call StrStr 70 Pop $2 71 StrCmp $2 "" "" AddToPath_done 72 Push "$1;" 73 Push "$0\;" 74 Call StrStr 75 Pop $2 76 StrCmp $2 "" "" AddToPath_done 77 GetFullPathName /SHORT $3 $0 78 Push "$1;" 79 Push "$3;" 80 Call StrStr 81 Pop $2 82 StrCmp $2 "" "" AddToPath_done 83 Push "$1;" 84 Push "$3\;" 85 Call StrStr 86 Pop $2 87 StrCmp $2 "" "" AddToPath_done 88 89 Call IsNT 90 Pop $1 91 StrCmp $1 1 AddToPath_NT 92 ; Not on NT 93 StrCpy $1 $WINDIR 2 94 FileOpen $1 "$1\autoexec.bat" a 95 FileSeek $1 -1 END 96 FileReadByte $1 $2 97 IntCmp $2 26 0 +2 +2 # DOS EOF 98 FileSeek $1 -1 END # write over EOF 99 FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" 100 FileClose $1 101 SetRebootFlag true 102 Goto AddToPath_done 103 104 AddToPath_NT: 105 ReadRegStr $1 ${WriteEnvStr_RegKey} "PATH" 106 StrCpy $2 $1 1 -1 # copy last char 107 StrCmp $2 ";" 0 +2 # if last char == ; 108 StrCpy $1 $1 -1 # remove last char 109 StrCmp $1 "" AddToPath_NTdoIt 110 StrCpy $0 "$0;$1" 111 AddToPath_NTdoIt: 112 WriteRegExpandStr ${WriteEnvStr_RegKey} "PATH" $0 113 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 114 115 AddToPath_done: 116 Pop $3 117 Pop $2 118 Pop $1 119 Pop $0 120FunctionEnd 121 122; RemoveFromPath - Remove a given dir from the path 123; Input: head of the stack 124 125Function un.RemoveFromPath 126 Exch $0 127 Push $1 128 Push $2 129 Push $3 130 Push $4 131 Push $5 132 Push $6 133 134 IntFmt $6 "%c" 26 # DOS EOF 135 136 Call un.IsNT 137 Pop $1 138 StrCmp $1 1 unRemoveFromPath_NT 139 ; Not on NT 140 StrCpy $1 $WINDIR 2 141 FileOpen $1 "$1\autoexec.bat" r 142 GetTempFileName $4 143 FileOpen $2 $4 w 144 GetFullPathName /SHORT $0 $0 145 StrCpy $0 "SET PATH=%PATH%;$0" 146 Goto unRemoveFromPath_dosLoop 147 148 unRemoveFromPath_dosLoop: 149 FileRead $1 $3 150 StrCpy $5 $3 1 -1 # read last char 151 StrCmp $5 $6 0 +2 # if DOS EOF 152 StrCpy $3 $3 -1 # remove DOS EOF so we can compare 153 StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine 154 StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine 155 StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine 156 StrCmp $3 "" unRemoveFromPath_dosLoopEnd 157 FileWrite $2 $3 158 Goto unRemoveFromPath_dosLoop 159 unRemoveFromPath_dosLoopRemoveLine: 160 SetRebootFlag true 161 Goto unRemoveFromPath_dosLoop 162 163 unRemoveFromPath_dosLoopEnd: 164 FileClose $2 165 FileClose $1 166 StrCpy $1 $WINDIR 2 167 Delete "$1\autoexec.bat" 168 CopyFiles /SILENT $4 "$1\autoexec.bat" 169 Delete $4 170 Goto unRemoveFromPath_done 171 172 unRemoveFromPath_NT: 173 ReadRegStr $1 ${WriteEnvStr_RegKey} "PATH" 174 StrCpy $5 $1 1 -1 # copy last char 175 StrCmp $5 ";" +2 # if last char != ; 176 StrCpy $1 "$1;" # append ; 177 Push $1 178 Push "$0;" 179 Call un.StrStr ; Find `$0;` in $1 180 Pop $2 ; pos of our dir 181 StrCmp $2 "" unRemoveFromPath_done 182 ; else, it is in path 183 # $0 - path to add 184 # $1 - path var 185 StrLen $3 "$0;" 186 StrLen $4 $2 187 StrCpy $5 $1 -$4 # $5 is now the part before the path to remove 188 StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove 189 StrCpy $3 $5$6 190 191 StrCpy $5 $3 1 -1 # copy last char 192 StrCmp $5 ";" 0 +2 # if last char == ; 193 StrCpy $3 $3 -1 # remove last char 194 195 WriteRegExpandStr ${WriteEnvStr_RegKey} "PATH" $3 196 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 197 198 unRemoveFromPath_done: 199 Pop $6 200 Pop $5 201 Pop $4 202 Pop $3 203 Pop $2 204 Pop $1 205 Pop $0 206FunctionEnd 207 208 209 210; AddToEnvVar - Adds the given value to the given environment var 211; Input - head of the stack $0 environement variable $1=value to add 212; Note - Win9x systems requires reboot 213 214Function AddToEnvVar 215 216 Exch $1 ; $1 has environment variable value 217 Exch 218 Exch $0 ; $0 has environment variable name 219 220 DetailPrint "Adding $1 to $0" 221 Push $2 222 Push $3 223 Push $4 224 225 226 ReadEnvStr $2 $0 227 Push "$2;" 228 Push "$1;" 229 Call StrStr 230 Pop $3 231 StrCmp $3 "" "" AddToEnvVar_done 232 233 Push "$2;" 234 Push "$1\;" 235 Call StrStr 236 Pop $3 237 StrCmp $3 "" "" AddToEnvVar_done 238 239 240 Call IsNT 241 Pop $2 242 StrCmp $2 1 AddToEnvVar_NT 243 ; Not on NT 244 StrCpy $2 $WINDIR 2 245 FileOpen $2 "$2\autoexec.bat" a 246 FileSeek $2 -1 END 247 FileReadByte $2 $3 248 IntCmp $3 26 0 +2 +2 # DOS EOF 249 FileSeek $2 -1 END # write over EOF 250 FileWrite $2 "$\r$\nSET $0=%$0%;$4$\r$\n" 251 FileClose $2 252 SetRebootFlag true 253 Goto AddToEnvVar_done 254 255 AddToEnvVar_NT: 256 ReadRegStr $2 ${WriteEnvStr_RegKey} $0 257 StrCpy $3 $2 1 -1 # copy last char 258 StrCmp $3 ";" 0 +2 # if last char == ; 259 StrCpy $2 $2 -1 # remove last char 260 StrCmp $2 "" AddToEnvVar_NTdoIt 261 StrCpy $1 "$2;$1" 262 AddToEnvVar_NTdoIt: 263 WriteRegExpandStr ${WriteEnvStr_RegKey} $0 $1 264 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 265 266 AddToEnvVar_done: 267 Pop $4 268 Pop $3 269 Pop $2 270 Pop $1 271 Pop $0 272 273FunctionEnd 274 275; RemoveFromEnvVar - Remove a given value from a environment var 276; Input: head of the stack 277 278Function un.RemoveFromEnvVar 279 280 Exch $1 ; $1 has environment variable value 281 Exch 282 Exch $0 ; $0 has environment variable name 283 284 DetailPrint "Removing $1 from $0" 285 Push $2 286 Push $3 287 Push $4 288 Push $5 289 Push $6 290 Push $7 291 292 IntFmt $7 "%c" 26 # DOS EOF 293 294 Call un.IsNT 295 Pop $2 296 StrCmp $2 1 unRemoveFromEnvVar_NT 297 ; Not on NT 298 StrCpy $2 $WINDIR 2 299 FileOpen $2 "$2\autoexec.bat" r 300 GetTempFileName $5 301 FileOpen $3 $5 w 302 GetFullPathName /SHORT $1 $1 303 StrCpy $1 "SET $0=%$0%;$1" 304 Goto unRemoveFromEnvVar_dosLoop 305 306 unRemoveFromEnvVar_dosLoop: 307 FileRead $2 $4 308 StrCpy $6 $4 1 -1 # read last char 309 StrCmp $6 $7 0 +2 # if DOS EOF 310 StrCpy $4 $4 -1 # remove DOS EOF so we can compare 311 StrCmp $4 "$1$\r$\n" unRemoveFromEnvVar_dosLoopRemoveLine 312 StrCmp $4 "$1$\n" unRemoveFromEnvVar_dosLoopRemoveLine 313 StrCmp $4 "$1" unRemoveFromEnvVar_dosLoopRemoveLine 314 StrCmp $4 "" unRemoveFromEnvVar_dosLoopEnd 315 FileWrite $3 $4 316 Goto unRemoveFromEnvVar_dosLoop 317 unRemoveFromEnvVar_dosLoopRemoveLine: 318 SetRebootFlag true 319 Goto unRemoveFromEnvVar_dosLoop 320 321 unRemoveFromEnvVar_dosLoopEnd: 322 FileClose $3 323 FileClose $2 324 StrCpy $2 $WINDIR 2 325 Delete "$2\autoexec.bat" 326 CopyFiles /SILENT $5 "$2\autoexec.bat" 327 Delete $5 328 Goto unRemoveFromEnvVar_done 329 330 unRemoveFromEnvVar_NT: 331 ReadRegStr $2 ${WriteEnvStr_RegKey} $0 332 StrCpy $6 $2 1 -1 # copy last char 333 StrCmp $6 ";" +2 # if last char != ; 334 StrCpy $2 "$2;" # append ; 335 Push $2 336 Push "$1;" 337 Call un.StrStr ; Find `$1;` in $2 338 Pop $3 ; pos of our dir 339 StrCmp $3 "" unRemoveFromEnvVar_done 340 ; else, it is in path 341 # $1 - path to add 342 # $2 - path var 343 StrLen $4 "$1;" 344 StrLen $5 $3 345 StrCpy $6 $2 -$5 # $6 is now the part before the path to remove 346 StrCpy $7 $3 "" $4 # $7 is now the part after the path to remove 347 StrCpy $4 $6$7 348 349 StrCpy $6 $4 1 -1 # copy last char 350 StrCmp $6 ";" 0 +2 # if last char == ; 351 StrCpy $4 $4 -1 # remove last char 352 353 WriteRegExpandStr ${WriteEnvStr_RegKey} $0 $4 354 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 355 356 unRemoveFromEnvVar_done: 357 Pop $7 358 Pop $6 359 Pop $5 360 Pop $4 361 Pop $3 362 Pop $2 363 Pop $1 364 Pop $0 365FunctionEnd 366 367 368 369 370!ifndef IsNT_KiCHiK 371!define IsNT_KiCHiK 372 373########################################### 374# Utility Functions # 375########################################### 376 377; IsNT 378; no input 379; output, top of the stack = 1 if NT or 0 if not 380; 381; Usage: 382; Call IsNT 383; Pop $R0 384; ($R0 at this point is 1 or 0) 385 386!macro IsNT un 387Function ${un}IsNT 388 Push $0 389 ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion 390 StrCmp $0 "" 0 IsNT_yes 391 ; we are not NT. 392 Pop $0 393 Push 0 394 Return 395 396 IsNT_yes: 397 ; NT!!! 398 Pop $0 399 Push 1 400FunctionEnd 401!macroend 402!insertmacro IsNT "" 403!insertmacro IsNT "un." 404 405!endif ; IsNT_KiCHiK 406 407; StrStr 408; input, top of stack = string to search for 409; top of stack-1 = string to search in 410; output, top of stack (replaces with the portion of the string remaining) 411; modifies no other variables. 412; 413; Usage: 414; Push "this is a long ass string" 415; Push "ass" 416; Call StrStr 417; Pop $R0 418; ($R0 at this point is "ass string") 419 420!macro StrStr un 421Function ${un}StrStr 422Exch $R1 ; st=haystack,old$R1, $R1=needle 423 Exch ; st=old$R1,haystack 424 Exch $R2 ; st=old$R1,old$R2, $R2=haystack 425 Push $R3 426 Push $R4 427 Push $R5 428 StrLen $R3 $R1 429 StrCpy $R4 0 430 ; $R1=needle 431 ; $R2=haystack 432 ; $R3=len(needle) 433 ; $R4=cnt 434 ; $R5=tmp 435 loop: 436 StrCpy $R5 $R2 $R3 $R4 437 StrCmp $R5 $R1 done 438 StrCmp $R5 "" done 439 IntOp $R4 $R4 + 1 440 Goto loop 441done: 442 StrCpy $R1 $R2 "" $R4 443 Pop $R5 444 Pop $R4 445 Pop $R3 446 Pop $R2 447 Exch $R1 448FunctionEnd 449!macroend 450!insertmacro StrStr "" 451!insertmacro StrStr "un." 452 453!endif ; _AddToPath_nsh 454