mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Try EnVar_plugin for updating path.
This should be more robust and not fail after upgrading.
This commit is contained in:
		| @@ -24,6 +24,7 @@ install: | ||||
|     # Replace makensis.exe and files with special long string build. This should | ||||
|     # prevent issues when setting PATH during installation. | ||||
|     - 7z e "tools\nsis-3.05-strlen_8192.zip" -o"C:\Program Files (x86)\NSIS\" -y | ||||
|     - 7z e "tools\EnVar_plugin.zip" -o"C:\Program Files (x86)\NSIS\" -y | ||||
|     - build_win all | ||||
|     - refreshenv | ||||
|     # We need to reload vcvars after refreshing | ||||
|   | ||||
| @@ -20,7 +20,6 @@ VIFileVersion "${PRODUCT_VERSION}" | ||||
| # Includes | ||||
| !include "MultiUser.nsh" | ||||
| !include "MUI2.nsh" | ||||
| !include ".\tools\EnvVarUpdate.nsh" | ||||
| !include "LogicLib.nsh" | ||||
|  | ||||
| # Basics | ||||
| @@ -124,6 +123,15 @@ section "Janet" BfWSection | ||||
|     # Start Menu | ||||
|     createShortCut "$SMPROGRAMS\Janet.lnk" "$INSTDIR\bin\janet.exe" "" "$INSTDIR\logo.ico" | ||||
|  | ||||
|     # Update path | ||||
|     ${If} $MultiUser.InstallMode == "AllUsers" | ||||
|         EnVar::SetHKLM | ||||
|     ${Else} | ||||
|         EnVar::SetHKCU | ||||
|     ${EndIf} | ||||
|     EnVar::AddValue "PATH" "$INSTDIR\bin" | ||||
|     Pop $0 | ||||
|  | ||||
|     # Set up Environment variables | ||||
|     !insertmacro WriteEnv JANET_PATH "$INSTDIR\Library" | ||||
|     !insertmacro WriteEnv JANET_HEADERPATH "$INSTDIR\C" | ||||
| @@ -132,13 +140,6 @@ section "Janet" BfWSection | ||||
|  | ||||
|     SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 | ||||
|  | ||||
|     # Update path | ||||
|     ${If} $MultiUser.InstallMode == "AllUsers" | ||||
|         ${EnvVarUpdate} $0 "PATH" "A" "HKLM" "$INSTDIR\bin" ; Append | ||||
|     ${Else} | ||||
|         ${EnvVarUpdate} $0 "PATH" "A" "HKCU" "$INSTDIR\bin" ; Append | ||||
|     ${EndIf} | ||||
|  | ||||
|     # Registry information for add/remove programs | ||||
|     WriteRegStr SHCTX "${UNINST_KEY}" "DisplayName" "Janet" | ||||
|     WriteRegStr SHCTX "${UNINST_KEY}" "InstallLocation" "$INSTDIR" | ||||
| @@ -185,10 +186,12 @@ section "uninstall" | ||||
|  | ||||
|     # Unset PATH | ||||
|     ${If} $MultiUser.InstallMode == "AllUsers" | ||||
|         ${un.EnvVarUpdate} $0 "PATH" "R" "HKLM" "$INSTDIR\bin" ; Remove | ||||
|         EnVar::SetHKLM | ||||
|     ${Else} | ||||
|         ${un.EnvVarUpdate} $0 "PATH" "R" "HKCU" "$INSTDIR\bin" ; Remove | ||||
|         EnVar::SetHKCU | ||||
|     ${EndIf} | ||||
|     EnVar::DeleteValue "PATH" "$INSTDIR\bin" | ||||
|     Pop $0 | ||||
|  | ||||
|     # make sure windows knows about the change | ||||
|     SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								tools/EnVar_plugin.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tools/EnVar_plugin.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,312 +0,0 @@ | ||||
| /** | ||||
|  *  EnvVarUpdate.nsh | ||||
|  *    : Environmental Variables: append, prepend, and remove entries | ||||
|  * | ||||
|  *     WARNING: If you use StrFunc.nsh header then include it before this file | ||||
|  *              with all required definitions. This is to avoid conflicts | ||||
|  * | ||||
|  *  Usage: | ||||
|  *    ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" | ||||
|  * | ||||
|  *  Credits: | ||||
|  *  Version 1.0  | ||||
|  *  * Cal Turney (turnec2) | ||||
|  *  * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this | ||||
|  *    function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, | ||||
|  *    WriteEnvStr, and un.DeleteEnvStr | ||||
|  *  * Diego Pedroso (deguix) for StrTok | ||||
|  *  * Kevin English (kenglish_hi) for StrContains | ||||
|  *  * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry   | ||||
|  *    (dandaman32) for StrReplace | ||||
|  * | ||||
|  *  Version 1.1 (compatibility with StrFunc.nsh) | ||||
|  *  * techtonik | ||||
|  * | ||||
|  *  http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries | ||||
|  * | ||||
|  */ | ||||
|   | ||||
|   | ||||
| !ifndef ENVVARUPDATE_FUNCTION | ||||
| !define ENVVARUPDATE_FUNCTION | ||||
| !verbose push | ||||
| !verbose 3 | ||||
| !include "LogicLib.nsh" | ||||
| !include "WinMessages.NSH" | ||||
| !include "StrFunc.nsh" | ||||
|   | ||||
| ; ---------------------------------- Macro Definitions ---------------------------------------- | ||||
| !macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString | ||||
|   Push "${EnvVarName}" | ||||
|   Push "${Action}" | ||||
|   Push "${RegLoc}" | ||||
|   Push "${PathString}" | ||||
|     Call EnvVarUpdate | ||||
|   Pop "${ResultVar}" | ||||
| !macroend | ||||
| !define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' | ||||
|   | ||||
| !macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString | ||||
|   Push "${EnvVarName}" | ||||
|   Push "${Action}" | ||||
|   Push "${RegLoc}" | ||||
|   Push "${PathString}" | ||||
|     Call un.EnvVarUpdate | ||||
|   Pop "${ResultVar}" | ||||
| !macroend | ||||
| !define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' | ||||
| ; ---------------------------------- Macro Definitions end------------------------------------- | ||||
|   | ||||
| ;----------------------------------- EnvVarUpdate start---------------------------------------- | ||||
| !define hklm_all_users     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' | ||||
| !define hkcu_current_user  'HKCU "Environment"' | ||||
|   | ||||
| !macro EnvVarUpdate UN | ||||
|   | ||||
| Function ${UN}EnvVarUpdate | ||||
|   | ||||
|   Push $0 | ||||
|   Exch 4 | ||||
|   Exch $1 | ||||
|   Exch 3 | ||||
|   Exch $2 | ||||
|   Exch 2 | ||||
|   Exch $3 | ||||
|   Exch | ||||
|   Exch $4 | ||||
|   Push $5 | ||||
|   Push $6 | ||||
|   Push $7 | ||||
|   Push $8 | ||||
|   Push $9 | ||||
|   Push $R0 | ||||
|   | ||||
|   /* After this point: | ||||
|   ------------------------- | ||||
|      $0 = ResultVar     (returned) | ||||
|      $1 = EnvVarName    (input) | ||||
|      $2 = Action        (input) | ||||
|      $3 = RegLoc        (input) | ||||
|      $4 = PathString    (input) | ||||
|      $5 = Orig EnvVar   (read from registry) | ||||
|      $6 = Len of $0     (temp) | ||||
|      $7 = tempstr1      (temp) | ||||
|      $8 = Entry counter (temp) | ||||
|      $9 = tempstr2      (temp) | ||||
|      $R0 = tempChar     (temp)  */ | ||||
|   | ||||
|   ; Step 1:  Read contents of EnvVarName from RegLoc | ||||
|   ; | ||||
|   ; Check for empty EnvVarName | ||||
|   ${If} $1 == "" | ||||
|     SetErrors | ||||
|     DetailPrint "ERROR: EnvVarName is blank" | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Check for valid Action | ||||
|   ${If}    $2 != "A" | ||||
|   ${AndIf} $2 != "P" | ||||
|   ${AndIf} $2 != "R" | ||||
|     SetErrors | ||||
|     DetailPrint "ERROR: Invalid Action - must be A, P, or R" | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   ${EndIf} | ||||
|   | ||||
|   ${If} $3 == HKLM | ||||
|     ReadRegStr $5 ${hklm_all_users} $1     ; Get EnvVarName from all users into $5 | ||||
|   ${ElseIf} $3 == HKCU | ||||
|     ReadRegStr $5 ${hkcu_current_user} $1  ; Read EnvVarName from current user into $5 | ||||
|   ${Else} | ||||
|     SetErrors | ||||
|     DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Check for empty PathString | ||||
|   ${If} $4 == "" | ||||
|     SetErrors | ||||
|     DetailPrint "ERROR: PathString is blank" | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Make sure we've got some work to do | ||||
|   ${If} $5 == "" | ||||
|   ${AndIf} $2 == "R" | ||||
|     SetErrors | ||||
|     DetailPrint "$1 is empty - Nothing to remove" | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Step 2: Scrub EnvVar | ||||
|   ; | ||||
|   StrCpy $0 $5                             ; Copy the contents to $0 | ||||
|   ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or | ||||
|   ; after the last one are not removed here but instead in Step 3) | ||||
|   ${If} $0 != ""                           ; If EnvVar is not empty ... | ||||
|     ${Do} | ||||
|       ${${UN}StrStr} $7 $0 " ;" | ||||
|       ${If} $7 == "" | ||||
|         ${ExitDo} | ||||
|       ${EndIf} | ||||
|       ${${UN}StrRep} $0  $0 " ;" ";"         ; Remove '<space>;' | ||||
|     ${Loop} | ||||
|     ${Do} | ||||
|       ${${UN}StrStr} $7 $0 "; " | ||||
|       ${If} $7 == "" | ||||
|         ${ExitDo} | ||||
|       ${EndIf} | ||||
|       ${${UN}StrRep} $0  $0 "; " ";"         ; Remove ';<space>' | ||||
|     ${Loop} | ||||
|     ${Do} | ||||
|       ${${UN}StrStr} $7 $0 ";;"  | ||||
|       ${If} $7 == "" | ||||
|         ${ExitDo} | ||||
|       ${EndIf} | ||||
|       ${${UN}StrRep} $0  $0 ";;" ";" | ||||
|     ${Loop} | ||||
|   | ||||
|     ; Remove a leading or trailing semicolon from EnvVar | ||||
|     StrCpy  $7  $0 1 0 | ||||
|     ${If} $7 == ";" | ||||
|       StrCpy $0  $0 "" 1                   ; Change ';<EnvVar>' to '<EnvVar>' | ||||
|     ${EndIf} | ||||
|     StrLen $6 $0 | ||||
|     IntOp $6 $6 - 1 | ||||
|     StrCpy $7  $0 1 $6 | ||||
|     ${If} $7 == ";" | ||||
|      StrCpy $0  $0 $6                      ; Change ';<EnvVar>' to '<EnvVar>' | ||||
|     ${EndIf} | ||||
|     ; DetailPrint "Scrubbed $1: [$0]"      ; Uncomment to debug | ||||
|   ${EndIf} | ||||
|   | ||||
|   /* Step 3. Remove all instances of the target path/string (even if "A" or "P") | ||||
|      $6 = bool flag (1 = found and removed PathString) | ||||
|      $7 = a string (e.g. path) delimited by semicolon(s) | ||||
|      $8 = entry counter starting at 0 | ||||
|      $9 = copy of $0 | ||||
|      $R0 = tempChar      */ | ||||
|   | ||||
|   ${If} $5 != ""                           ; If EnvVar is not empty ... | ||||
|     StrCpy $9 $0 | ||||
|     StrCpy $0 "" | ||||
|     StrCpy $8 0 | ||||
|     StrCpy $6 0 | ||||
|   | ||||
|     ${Do} | ||||
|       ${${UN}StrTok} $7 $9 ";" $8 "0"      ; $7 = next entry, $8 = entry counter | ||||
|   | ||||
|       ${If} $7 == ""                       ; If we've run out of entries, | ||||
|         ${ExitDo}                          ;    were done | ||||
|       ${EndIf}                             ; | ||||
|   | ||||
|       ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) | ||||
|       ${Do} | ||||
|         StrCpy $R0  $7 1 | ||||
|         ${If} $R0 != " " | ||||
|           ${ExitDo} | ||||
|         ${EndIf} | ||||
|         StrCpy $7   $7 "" 1                ;  Remove leading space | ||||
|       ${Loop} | ||||
|       ${Do} | ||||
|         StrCpy $R0  $7 1 -1 | ||||
|         ${If} $R0 != " " | ||||
|           ${ExitDo} | ||||
|         ${EndIf} | ||||
|         StrCpy $7   $7 -1                  ;  Remove trailing space | ||||
|       ${Loop} | ||||
|       ${If} $7 == $4                       ; If string matches, remove it by not appending it | ||||
|         StrCpy $6 1                        ; Set 'found' flag | ||||
|       ${ElseIf} $7 != $4                   ; If string does NOT match | ||||
|       ${AndIf}  $0 == ""                   ;    and the 1st string being added to $0, | ||||
|         StrCpy $0 $7                       ;    copy it to $0 without a prepended semicolon | ||||
|       ${ElseIf} $7 != $4                   ; If string does NOT match | ||||
|       ${AndIf}  $0 != ""                   ;    and this is NOT the 1st string to be added to $0, | ||||
|         StrCpy $0 $0;$7                    ;    append path to $0 with a prepended semicolon | ||||
|       ${EndIf}                             ; | ||||
|   | ||||
|       IntOp $8 $8 + 1                      ; Bump counter | ||||
|     ${Loop}                                ; Check for duplicates until we run out of paths | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Step 4:  Perform the requested Action | ||||
|   ; | ||||
|   ${If} $2 != "R"                          ; If Append or Prepend | ||||
|     ${If} $6 == 1                          ; And if we found the target | ||||
|       DetailPrint "Target is already present in $1. It will be removed and" | ||||
|     ${EndIf} | ||||
|     ${If} $0 == ""                         ; If EnvVar is (now) empty | ||||
|       StrCpy $0 $4                         ;   just copy PathString to EnvVar | ||||
|       ${If} $6 == 0                        ; If found flag is either 0 | ||||
|       ${OrIf} $6 == ""                     ; or blank (if EnvVarName is empty) | ||||
|         DetailPrint "$1 was empty and has been updated with the target" | ||||
|       ${EndIf} | ||||
|     ${ElseIf} $2 == "A"                    ;  If Append (and EnvVar is not empty), | ||||
|       StrCpy $0 $0;$4                      ;     append PathString | ||||
|       ${If} $6 == 1 | ||||
|         DetailPrint "appended to $1" | ||||
|       ${Else} | ||||
|         DetailPrint "Target was appended to $1" | ||||
|       ${EndIf} | ||||
|     ${Else}                                ;  If Prepend (and EnvVar is not empty), | ||||
|       StrCpy $0 $4;$0                      ;     prepend PathString | ||||
|       ${If} $6 == 1 | ||||
|         DetailPrint "prepended to $1" | ||||
|       ${Else} | ||||
|         DetailPrint "Target was prepended to $1" | ||||
|       ${EndIf} | ||||
|     ${EndIf} | ||||
|   ${Else}                                  ; If Action = Remove | ||||
|     ${If} $6 == 1                          ;   and we found the target | ||||
|       DetailPrint "Target was found and removed from $1" | ||||
|     ${Else} | ||||
|       DetailPrint "Target was NOT found in $1 (nothing to remove)" | ||||
|     ${EndIf} | ||||
|     ${If} $0 == "" | ||||
|       DetailPrint "$1 is now empty" | ||||
|     ${EndIf} | ||||
|   ${EndIf} | ||||
|   | ||||
|   ; Step 5:  Update the registry at RegLoc with the updated EnvVar and announce the change | ||||
|   ; | ||||
|   ClearErrors | ||||
|   ${If} $3  == HKLM | ||||
|     WriteRegExpandStr ${hklm_all_users} $1 $0     ; Write it in all users section | ||||
|   ${ElseIf} $3 == HKCU | ||||
|     WriteRegExpandStr ${hkcu_current_user} $1 $0  ; Write it to current user section | ||||
|   ${EndIf} | ||||
|   | ||||
|   IfErrors 0 +4 | ||||
|     MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" | ||||
|     DetailPrint "Could not write updated $1 to $3" | ||||
|     Goto EnvVarUpdate_Restore_Vars | ||||
|   | ||||
|   ; "Export" our change | ||||
|   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 | ||||
|   | ||||
|   EnvVarUpdate_Restore_Vars: | ||||
|   ; | ||||
|   ; Restore the user's variables and return ResultVar | ||||
|   Pop $R0 | ||||
|   Pop $9 | ||||
|   Pop $8 | ||||
|   Pop $7 | ||||
|   Pop $6 | ||||
|   Pop $5 | ||||
|   Pop $4 | ||||
|   Pop $3 | ||||
|   Pop $2 | ||||
|   Pop $1 | ||||
|   Push $0  ; Push my $0 (ResultVar) | ||||
|   Exch | ||||
|   Pop $0   ; Restore his $0 | ||||
|   | ||||
| FunctionEnd | ||||
|   | ||||
| !macroend   ; EnvVarUpdate UN | ||||
| !insertmacro EnvVarUpdate "" | ||||
| !insertmacro EnvVarUpdate "un." | ||||
| ;----------------------------------- EnvVarUpdate end---------------------------------------- | ||||
|   | ||||
| !verbose pop | ||||
| !endif | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose