Skip to content

Commit 231ca47

Browse files
committed
Windows installer: More robust and less error-prone PATH changing
1 parent 3f53994 commit 231ca47

File tree

1 file changed

+89
-232
lines changed

1 file changed

+89
-232
lines changed

makepanda/installer.nsi

Lines changed: 89 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -886,25 +886,37 @@ Function AddToPath
886886
Goto AddToPath_done
887887

888888
AddToPath_NT:
889+
ClearErrors
889890
ReadRegStr $1 HKCU "Environment" "PATH"
890-
Call IsUserAdmin
891-
Pop $3
892-
; If this is an Admin user, use the System env. variable instead of the user's env. variable
893-
StrCmp $3 1 0 +2
894-
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
895891

896-
; If the PATH string is empty, WATCH OUT. This probably means
897-
; the PATH surpassed NSIS' string limit. Don't overwrite it!
898-
; The only thing we can do is display an error message.
899-
StrCmp $1 "" AddToPath_EmptyError
892+
; If we reached an error, WATCH OUT. Either this means that
893+
; the registry key did not exist, or that it didn't fit in
894+
; NSIS' string limit. If the latter, we have to be very
895+
; careful not to overwrite the user's PATH.
896+
IfErrors AddToPath_Error
897+
DetailPrint "Current PATH value is set to $1"
898+
StrCmp $1 "" AddToPath_NTAddPath
900899

901900
; Pull off the last character of the PATH string. If it's a semicolon,
902901
; we don't need to add another one, so jump to the section where we
903902
; append the new PATH component(s).
904903
StrCpy $2 $1 1 -1
905904
StrCmp $2 ";" AddToPath_NTAddPath AddToPath_NTAddSemi
906905

907-
AddToPath_EmptyError:
906+
AddToPath_Error:
907+
DetailPrint "Encountered error reading PATH variable."
908+
; Does the variable exist? If it doesn't, then the
909+
; error happened because we need to create the
910+
; variable. If it does, then we failed to read it
911+
; because we reached NSIS' string limit.
912+
StrCpy $3 0
913+
AddToPath_loop:
914+
EnumRegValue $4 HKCU "Environment" $3
915+
StrCmp $4 "PATH" AddToPath_ExceedLimit
916+
StrCmp $4 "" AddToPath_NTAddPath
917+
IntOp $3 $3 + 1
918+
Goto AddToPath_loop
919+
AddToPath_ExceedLimit:
908920
MessageBox MB_ABORTRETRYIGNORE|MB_ICONEXCLAMATION "Your PATH environment variable is too long! Please remove extraneous entries before proceeding. Panda3D needs to add the following the PATH so that the Panda3D utilities and libraries can be located correctly.$\n$\n$0$\n$\nIf you wish to add Panda3D to the path yourself, choose Ignore." IDIGNORE AddToPath_done IDRETRY AddToPath_NT
909921
SetDetailsPrint both
910922
DetailPrint "Cannot append to PATH - variable is likely too long."
@@ -915,16 +927,7 @@ Function AddToPath
915927
Goto AddToPath_NTAddPath
916928
AddToPath_NTAddPath:
917929
StrCpy $0 "$1$0"
918-
Goto AddToPath_NTdoIt
919-
AddToPath_NTdoIt:
920-
Call IsUserAdmin
921-
Pop $3
922-
StrCmp $3 1 0 NotAdmin
923-
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0
924-
Goto AddToPath_done
925-
926-
NotAdmin:
927-
WriteRegExpandStr HKCU "Environment" "PATH" $0
930+
WriteRegExpandStr HKCU "Environment" "PATH" $0
928931
AddToPath_done:
929932
Pop $3
930933
Pop $2
@@ -975,42 +978,40 @@ Function RemoveFromPath
975978
Goto unRemoveFromPath_done
976979

977980
unRemoveFromPath_NT:
981+
Push $0
978982
StrLen $2 $0
979-
Call IsUserAdmin
980-
Pop $5
981-
StrCmp $5 1 0 NotAdmin
982-
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
983-
Push $1
984-
Push $0
985-
Call StrStr ; Find $0 in $1
986-
Pop $0 ; pos of our dir
987-
IntCmp $0 -1 unRemoveFromPath_done
988-
; else, it is in path
989-
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
990-
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
991-
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
992-
StrLen $0 $1
993-
StrCpy $1 $1 $0 $2
994-
StrCpy $3 "$3$1"
995-
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
996-
Goto unRemoveFromPath_done
997-
998-
999-
NotAdmin:
1000-
ReadRegStr $1 HKCU "Environment" "PATH"
1001-
Push $1
1002-
Push $0
1003-
Call StrStr ; Find $0 in $1
1004-
Pop $0 ; pos of our dir
1005-
IntCmp $0 -1 unRemoveFromPath_done
1006-
; else, it is in path
1007-
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1008-
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1009-
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1010-
StrLen $0 $1
1011-
StrCpy $1 $1 $0 $2
1012-
StrCpy $3 "$3$1"
1013-
WriteRegExpandStr HKCU "Environment" "PATH" $3
983+
ReadRegStr $1 HKCU "Environment" "PATH"
984+
Push $1
985+
Push $0
986+
Call StrStr ; Find $0 in $1
987+
Pop $0 ; pos of our dir
988+
IntCmp $0 -1 unRemoveFromPath_NT_System
989+
; else, it is in path
990+
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
991+
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
992+
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
993+
StrLen $0 $1
994+
StrCpy $1 $1 $0 $2
995+
StrCpy $3 "$3$1"
996+
WriteRegExpandStr HKCU "Environment" "PATH" $3
997+
998+
unRemoveFromPath_NT_System:
999+
Pop $0
1000+
StrLen $2 $0
1001+
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
1002+
Push $1
1003+
Push $0
1004+
Call StrStr ; Find $0 in $1
1005+
Pop $0 ; pos of our dir
1006+
IntCmp $0 -1 unRemoveFromPath_done
1007+
; else, it is in path
1008+
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1009+
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1010+
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1011+
StrLen $0 $1
1012+
StrCpy $1 $1 $0 $2
1013+
StrCpy $3 "$3$1"
1014+
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
10141015

10151016
unRemoveFromPath_done:
10161017
Pop $5
@@ -1061,42 +1062,40 @@ Function un.RemoveFromPath
10611062
Goto unRemoveFromPath_done
10621063

10631064
unRemoveFromPath_NT:
1065+
Push $0
10641066
StrLen $2 $0
1065-
Call un.IsUserAdmin
1066-
Pop $5
1067-
StrCmp $5 1 0 NotAdmin
1068-
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
1069-
Push $1
1070-
Push $0
1071-
Call un.StrStr ; Find $0 in $1
1072-
Pop $0 ; pos of our dir
1073-
IntCmp $0 -1 unRemoveFromPath_done
1074-
; else, it is in path
1075-
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1076-
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1077-
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1078-
StrLen $0 $1
1079-
StrCpy $1 $1 $0 $2
1080-
StrCpy $3 "$3$1"
1081-
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
1082-
Goto unRemoveFromPath_done
1083-
1084-
1085-
NotAdmin:
1086-
ReadRegStr $1 HKCU "Environment" "PATH"
1087-
Push $1
1088-
Push $0
1089-
Call un.StrStr ; Find $0 in $1
1090-
Pop $0 ; pos of our dir
1091-
IntCmp $0 -1 unRemoveFromPath_done
1092-
; else, it is in path
1093-
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1094-
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1095-
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1096-
StrLen $0 $1
1097-
StrCpy $1 $1 $0 $2
1098-
StrCpy $3 "$3$1"
1099-
WriteRegExpandStr HKCU "Environment" "PATH" $3
1067+
ReadRegStr $1 HKCU "Environment" "PATH"
1068+
Push $1
1069+
Push $0
1070+
Call un.StrStr ; Find $0 in $1
1071+
Pop $0 ; pos of our dir
1072+
IntCmp $0 -1 unRemoveFromPath_NT_System
1073+
; else, it is in path
1074+
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1075+
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1076+
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1077+
StrLen $0 $1
1078+
StrCpy $1 $1 $0 $2
1079+
StrCpy $3 "$3$1"
1080+
WriteRegExpandStr HKCU "Environment" "PATH" $3
1081+
1082+
unRemoveFromPath_NT_System:
1083+
Pop $0
1084+
StrLen $2 $0
1085+
ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
1086+
Push $1
1087+
Push $0
1088+
Call un.StrStr ; Find $0 in $1
1089+
Pop $0 ; pos of our dir
1090+
IntCmp $0 -1 unRemoveFromPath_done
1091+
; else, it is in path
1092+
StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
1093+
IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
1094+
IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
1095+
StrLen $0 $1
1096+
StrCpy $1 $1 $0 $2
1097+
StrCpy $3 "$3$1"
1098+
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
11001099

11011100
unRemoveFromPath_done:
11021101
Pop $5
@@ -1107,148 +1106,6 @@ Function un.RemoveFromPath
11071106
Pop $0
11081107
FunctionEnd
11091108

1110-
; From: http://nsis.sourceforge.net/archive/nsisweb.php?page=329&instances=0,11
1111-
; Localized by Ben Johnson (bkj@andrew.cmu.edu)
1112-
Function IsUserAdmin
1113-
Push $0
1114-
Push $1
1115-
Push $2
1116-
Push $3
1117-
Call IsNT
1118-
Pop $1
1119-
1120-
ClearErrors
1121-
UserInfo::GetName
1122-
;IfErrors Win9x
1123-
Pop $2
1124-
UserInfo::GetAccountType
1125-
Pop $3
1126-
1127-
; Compare results of IsNT with "1"
1128-
StrCmp $1 1 0 NotNT
1129-
;This is NT
1130-
1131-
1132-
StrCmp $3 "Admin" 0 NotAdmin
1133-
; Observation: I get here when running Win98SE. (Lilla)
1134-
; The functions UserInfo.dll looks for are there on Win98 too,
1135-
; but just don't work. So UserInfo.dll, knowing that admin isn't required
1136-
; on Win98, returns admin anyway. (per kichik)
1137-
; MessageBox MB_OK 'User "$R1" is in the Administrators group'
1138-
Pop $3
1139-
Pop $2
1140-
Pop $1
1141-
Pop $0
1142-
1143-
Push 1
1144-
Return
1145-
1146-
NotAdmin:
1147-
; You should still check for an empty string because the functions
1148-
; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
1149-
1150-
#StrCmp $2 "" Win9x
1151-
#StrCpy $0 0
1152-
;MessageBox MB_OK 'User "$2" is in the "$3" group'
1153-
Pop $3
1154-
Pop $2
1155-
Pop $1
1156-
Pop $0
1157-
1158-
Push 0
1159-
Return
1160-
1161-
;Because we use IsNT, this is redundant.
1162-
#Win9x:
1163-
# ; comment/message below is by UserInfo.nsi author:
1164-
# ; This one means you don't need to care about admin or
1165-
# ; not admin because Windows 9x doesn't either
1166-
# ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
1167-
# StrCpy $0 0
1168-
1169-
NotNT:
1170-
;We are not NT
1171-
;Win9x doesn't have "admin" users.
1172-
;Let the user do whatever.
1173-
Pop $3
1174-
Pop $2
1175-
Pop $1
1176-
Pop $0
1177-
1178-
Push 1
1179-
1180-
FunctionEnd
1181-
1182-
Function un.IsUserAdmin
1183-
Push $0
1184-
Push $1
1185-
Push $2
1186-
Push $3
1187-
Call un.IsNT
1188-
Pop $1
1189-
1190-
ClearErrors
1191-
UserInfo::GetName
1192-
;IfErrors Win9x
1193-
Pop $2
1194-
UserInfo::GetAccountType
1195-
Pop $3
1196-
1197-
; Compare results of IsNT with "1"
1198-
StrCmp $1 1 0 NotNT
1199-
;This is NT
1200-
1201-
1202-
StrCmp $3 "Admin" 0 NotAdmin
1203-
; Observation: I get here when running Win98SE. (Lilla)
1204-
; The functions UserInfo.dll looks for are there on Win98 too,
1205-
; but just don't work. So UserInfo.dll, knowing that admin isn't required
1206-
; on Win98, returns admin anyway. (per kichik)
1207-
; MessageBox MB_OK 'User "$R1" is in the Administrators group'
1208-
Pop $3
1209-
Pop $2
1210-
Pop $1
1211-
Pop $0
1212-
1213-
Push 1
1214-
Return
1215-
1216-
NotAdmin:
1217-
; You should still check for an empty string because the functions
1218-
; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
1219-
1220-
#StrCmp $2 "" Win9x
1221-
#StrCpy $0 0
1222-
;MessageBox MB_OK 'User "$2" is in the "$3" group'
1223-
Pop $3
1224-
Pop $2
1225-
Pop $1
1226-
Pop $0
1227-
1228-
Push 0
1229-
Return
1230-
1231-
;Because we use IsNT, this is redundant.
1232-
#Win9x:
1233-
# ; comment/message below is by UserInfo.nsi author:
1234-
# ; This one means you don't need to care about admin or
1235-
# ; not admin because Windows 9x doesn't either
1236-
# ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
1237-
# StrCpy $0 0
1238-
1239-
NotNT:
1240-
;We are not NT
1241-
;Win9x doesn't have "admin" users.
1242-
;Let the user do whatever.
1243-
Pop $3
1244-
Pop $2
1245-
Pop $1
1246-
Pop $0
1247-
1248-
Push 1
1249-
1250-
FunctionEnd
1251-
12521109
Function StrRep
12531110

12541111
;Written by dirtydingus 2003-02-20 04:30:09

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy