summary refs log tree commit diff stats
path: root/tools/niminst
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2016-09-30 23:22:27 +0200
committerDominik Picheta <dominikpicheta@gmail.com>2016-09-30 23:23:20 +0200
commit331d4ab07d04989a4822a344e84b02c0b9668a65 (patch)
tree80e03104daee4183e0f6d18e6aa7bf71bab3145e /tools/niminst
parentd17709cc46ddb088420ac070430381c8ab251acd (diff)
downloadNim-331d4ab07d04989a4822a344e84b02c0b9668a65.tar.gz
CI: Fixes PATH handling in NSIS installers.
Squashed commit of the following:

commit 82d16908d6b4dacc585c241005f49aea2eef2c9f
Author: Dominik Picheta <dominikpicheta@gmail.com>
Date:   Fri Sep 30 22:20:47 2016 +0200

    CI: ugh, another try.

commit 6fe7e2fad11851ad568f9156132bf186593d2c0d
Author: Dominik Picheta <dominikpicheta@gmail.com>
Date:   Fri Sep 30 21:48:22 2016 +0200

    CI: Fix env PATH setting issues in NSIS installer.
Diffstat (limited to 'tools/niminst')
-rw-r--r--tools/niminst/nsis.tmpl211
1 files changed, 199 insertions, 12 deletions
diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl
index 64dcc8f8b..247d02d1d 100644
--- a/tools/niminst/nsis.tmpl
+++ b/tools/niminst/nsis.tmpl
@@ -11,10 +11,6 @@
   ; File Functions Header, used to get the current drive root.
   !include "FileFunc.nsh"
 
-  ; *Patched* Environment Variable Manipulation Header, used to add
-  ; tools to the user's PATH environment variable.
-  !include "EnvVarUpdate.nsh"
-
 ;--------------------------------
 ; Global variables and defines
   !define PRODUCT_NAME "?c.displayName"
@@ -156,10 +152,14 @@
 
   ; Section for adding tools to the PATH variable
   Section "Setup Path Environment" PathSection
-     ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\dist\mingw"
-     ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\dist\mingw\bin"
-     ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$INSTDIR\bin"
-     ${EnvVarUpdate} $R0 "PATH" "A" "HKCU" "$PROFILE\.nimble\bin"
+    Push "$INSTDIR\bin"
+    Call AddToPath
+    Push "$INSTDIR\dist\mingw"
+    Call AddToPath
+    Push "$INSTDIR\dist\mingw\bin"
+    Call AddToPath
+    Push "$PROFILE\.nimble\bin"
+    Call AddToPath
   SectionEnd
 
   ; The downloadable sections. These sections are automatically generated by
@@ -243,10 +243,14 @@
     SetAutoClose true
 
     ; Remove entries from the PATH environment variable
-    ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\dist\mingw"
-    ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\dist\mingw\bin"
-    ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$INSTDIR\bin"
-    ${un.EnvVarUpdate} $R0 "PATH" "R" "HKCU" "$PROFILE\.nimble\bin"
+    Push "$INSTDIR\bin"
+    Call un.RemoveFromPath
+    Push "$INSTDIR\dist\mingw"
+    Call un.RemoveFromPath
+    Push "$INSTDIR\dist\mingw\bin"
+    Call un.RemoveFromPath
+    Push "$PROFILE\.nimble\bin"
+    Call un.RemoveFromPath
   SectionEnd
 
 ;--------------------------------
@@ -256,3 +260,186 @@
     ${GetRoot} "$EXEDIR" $R0
     ;strCpy $INSTDIR "$R0\?{c.name}"
   FunctionEnd
+
+
+;--------------------------------------------------------------------
+; Path functions
+;
+; Based on example from:
+; http://nsis.sourceforge.net/Path_Manipulation
+;
+; Actually based on:
+; https://www.smartmontools.org/browser/trunk/smartmontools/os_win32/installer.nsi#L636
+
+
+!include "WinMessages.nsh"
+
+; Registry Entry for environment (NT4,2000,XP)
+; All users:
+;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+; Current user only:
+!define Environ 'HKCU "Environment"'
+
+
+; AddToPath - Appends dir to PATH
+;   (does not work on Win9x/ME)
+;
+; Usage:
+;   Push "dir"
+;   Call AddToPath
+
+Function AddToPath
+  Exch $0
+  Push $1
+  Push $2
+  Push $3
+  Push $4
+
+  ; NSIS ReadRegStr returns empty string on string overflow
+  ; Native calls are used here to check actual length of PATH
+
+  ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3)
+  System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4"
+  IntCmp $4 0 0 done done
+  ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
+  ; RegCloseKey($3)
+  System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
+  System::Call "advapi32::RegCloseKey(i $3)"
+
+  IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
+    DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
+    MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
+    Goto done
+
+  IntCmp $4 0 +5 ; $4 != NO_ERROR
+    IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
+      DetailPrint "AddToPath: unexpected error code $4"
+      Goto done
+    StrCpy $1 ""
+
+  ; Check if already in PATH
+  Push "$1;"
+  Push "$0;"
+  Call StrStr
+  Pop $2
+  StrCmp $2 "" 0 done
+  Push "$1;"
+  Push "$0\;"
+  Call StrStr
+  Pop $2
+  StrCmp $2 "" 0 done
+
+  ; Prevent NSIS string overflow
+  StrLen $2 $0
+  StrLen $3 $1
+  IntOp $2 $2 + $3
+  IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
+  IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
+    DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
+    MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}."
+    Goto done
+
+  ; Append dir to PATH
+  DetailPrint "Add to PATH: $0"
+  StrCpy $2 $1 1 -1
+  StrCmp $2 ";" 0 +2
+    StrCpy $1 $1 -1 ; remove trailing ';'
+  StrCmp $1 "" +2   ; no leading ';'
+    StrCpy $0 "$1;$0"
+  WriteRegExpandStr ${Environ} "PATH" $0
+  SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+done:
+  Pop $4
+  Pop $3
+  Pop $2
+  Pop $1
+  Pop $0
+FunctionEnd
+
+
+; RemoveFromPath - Removes dir from PATH
+;
+; Usage:
+;   Push "dir"
+;   Call RemoveFromPath
+
+Function un.RemoveFromPath
+  Exch $0
+  Push $1
+  Push $2
+  Push $3
+  Push $4
+  Push $5
+  Push $6
+
+  ReadRegStr $1 ${Environ} "PATH"
+  StrCpy $5 $1 1 -1
+  StrCmp $5 ";" +2
+    StrCpy $1 "$1;" ; ensure trailing ';'
+  Push $1
+  Push "$0;"
+  Call un.StrStr
+  Pop $2 ; pos of our dir
+  StrCmp $2 "" done
+
+  DetailPrint "Remove from PATH: $0"
+  StrLen $3 "$0;"
+  StrLen $4 $2
+  StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
+  StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
+  StrCpy $3 "$5$6"
+  StrCpy $5 $3 1 -1
+  StrCmp $5 ";" 0 +2
+    StrCpy $3 $3 -1 ; remove trailing ';'
+  WriteRegExpandStr ${Environ} "PATH" $3
+  SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+done:
+  Pop $6
+  Pop $5
+  Pop $4
+  Pop $3
+  Pop $2
+  Pop $1
+  Pop $0
+FunctionEnd
+
+
+; StrStr - find substring in a string
+;
+; Usage:
+;   Push "this is some string"
+;   Push "some"
+;   Call StrStr
+;   Pop $0 ; "some string"
+
+!macro StrStr un
+Function ${un}StrStr
+  Exch $R1 ; $R1=substring, stack=[old$R1,string,...]
+  Exch     ;                stack=[string,old$R1,...]
+  Exch $R2 ; $R2=string,    stack=[old$R2,old$R1,...]
+  Push $R3
+  Push $R4
+  Push $R5
+  StrLen $R3 $R1
+  StrCpy $R4 0
+  ; $R1=substring, $R2=string, $R3=strlen(substring)
+  ; $R4=count, $R5=tmp
+  loop:
+    StrCpy $R5 $R2 $R3 $R4
+    StrCmp $R5 $R1 done
+    StrCmp $R5 "" done
+    IntOp $R4 $R4 + 1
+    Goto loop
+done:
+  StrCpy $R1 $R2 "" $R4
+  Pop $R5
+  Pop $R4
+  Pop $R3
+  Pop $R2
+  Exch $R1 ; $R1=old$R1, stack=[result,...]
+FunctionEnd
+!macroend
+!insertmacro StrStr ""
+!insertmacro StrStr "un."