Skip to content

Commit d61e8d3

Browse files
Added installer for windows targets
1 parent 1bff6e5 commit d61e8d3

File tree

7 files changed

+460
-24
lines changed

7 files changed

+460
-24
lines changed
File renamed without changes.

installer/EnvVarUpdate.nsh

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
/**
2+
* EnvVarUpdate.nsh
3+
* : Environmental Variables: append, prepend, and remove entries
4+
*
5+
* WARNING: If you use StrFunc.nsh header then include it before this file
6+
* with all required definitions. This is to avoid conflicts
7+
*
8+
* Usage:
9+
* ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString"
10+
*
11+
* Credits:
12+
* Version 1.0
13+
* * Cal Turney (turnec2)
14+
* * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this
15+
* function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar,
16+
* WriteEnvStr, and un.DeleteEnvStr
17+
* * Diego Pedroso (deguix) for StrTok
18+
* * Kevin English (kenglish_hi) for StrContains
19+
* * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry
20+
* (dandaman32) for StrReplace
21+
*
22+
* Version 1.1 (compatibility with StrFunc.nsh)
23+
* * techtonik
24+
*
25+
* http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries
26+
*
27+
*/
28+
29+
30+
!ifndef ENVVARUPDATE_FUNCTION
31+
!define ENVVARUPDATE_FUNCTION
32+
!verbose push
33+
!verbose 3
34+
!include "LogicLib.nsh"
35+
!include "WinMessages.NSH"
36+
!include "StrFunc.nsh"
37+
38+
; ---- Fix for conflict if StrFunc.nsh is already includes in main file -----------------------
39+
!macro _IncludeStrFunction StrFuncName
40+
!ifndef ${StrFuncName}_INCLUDED
41+
${${StrFuncName}}
42+
!endif
43+
!ifndef Un${StrFuncName}_INCLUDED
44+
${Un${StrFuncName}}
45+
!endif
46+
!define un.${StrFuncName} "${Un${StrFuncName}}"
47+
!macroend
48+
49+
!insertmacro _IncludeStrFunction StrTok
50+
!insertmacro _IncludeStrFunction StrStr
51+
!insertmacro _IncludeStrFunction StrRep
52+
53+
; ---------------------------------- Macro Definitions ----------------------------------------
54+
!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
55+
Push "${EnvVarName}"
56+
Push "${Action}"
57+
Push "${RegLoc}"
58+
Push "${PathString}"
59+
Call EnvVarUpdate
60+
Pop "${ResultVar}"
61+
!macroend
62+
!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"'
63+
64+
!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
65+
Push "${EnvVarName}"
66+
Push "${Action}"
67+
Push "${RegLoc}"
68+
Push "${PathString}"
69+
Call un.EnvVarUpdate
70+
Pop "${ResultVar}"
71+
!macroend
72+
!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"'
73+
; ---------------------------------- Macro Definitions end-------------------------------------
74+
75+
;----------------------------------- EnvVarUpdate start----------------------------------------
76+
!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
77+
!define hkcu_current_user 'HKCU "Environment"'
78+
79+
!macro EnvVarUpdate UN
80+
81+
Function ${UN}EnvVarUpdate
82+
83+
Push $0
84+
Exch 4
85+
Exch $1
86+
Exch 3
87+
Exch $2
88+
Exch 2
89+
Exch $3
90+
Exch
91+
Exch $4
92+
Push $5
93+
Push $6
94+
Push $7
95+
Push $8
96+
Push $9
97+
Push $R0
98+
99+
/* After this point:
100+
-------------------------
101+
$0 = ResultVar (returned)
102+
$1 = EnvVarName (input)
103+
$2 = Action (input)
104+
$3 = RegLoc (input)
105+
$4 = PathString (input)
106+
$5 = Orig EnvVar (read from registry)
107+
$6 = Len of $0 (temp)
108+
$7 = tempstr1 (temp)
109+
$8 = Entry counter (temp)
110+
$9 = tempstr2 (temp)
111+
$R0 = tempChar (temp) */
112+
113+
; Step 1: Read contents of EnvVarName from RegLoc
114+
;
115+
; Check for empty EnvVarName
116+
${If} $1 == ""
117+
SetErrors
118+
DetailPrint "ERROR: EnvVarName is blank"
119+
Goto EnvVarUpdate_Restore_Vars
120+
${EndIf}
121+
122+
; Check for valid Action
123+
${If} $2 != "A"
124+
${AndIf} $2 != "P"
125+
${AndIf} $2 != "R"
126+
SetErrors
127+
DetailPrint "ERROR: Invalid Action - must be A, P, or R"
128+
Goto EnvVarUpdate_Restore_Vars
129+
${EndIf}
130+
131+
${If} $3 == HKLM
132+
ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5
133+
${ElseIf} $3 == HKCU
134+
ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5
135+
${Else}
136+
SetErrors
137+
DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"'
138+
Goto EnvVarUpdate_Restore_Vars
139+
${EndIf}
140+
141+
; Check for empty PathString
142+
${If} $4 == ""
143+
SetErrors
144+
DetailPrint "ERROR: PathString is blank"
145+
Goto EnvVarUpdate_Restore_Vars
146+
${EndIf}
147+
148+
; Make sure we've got some work to do
149+
${If} $5 == ""
150+
${AndIf} $2 == "R"
151+
SetErrors
152+
DetailPrint "$1 is empty - Nothing to remove"
153+
Goto EnvVarUpdate_Restore_Vars
154+
${EndIf}
155+
156+
; Step 2: Scrub EnvVar
157+
;
158+
StrCpy $0 $5 ; Copy the contents to $0
159+
; Remove spaces around semicolons (NOTE: spaces before the 1st entry or
160+
; after the last one are not removed here but instead in Step 3)
161+
${If} $0 != "" ; If EnvVar is not empty ...
162+
${Do}
163+
${${UN}StrStr} $7 $0 " ;"
164+
${If} $7 == ""
165+
${ExitDo}
166+
${EndIf}
167+
${${UN}StrRep} $0 $0 " ;" ";" ; Remove '<space>;'
168+
${Loop}
169+
${Do}
170+
${${UN}StrStr} $7 $0 "; "
171+
${If} $7 == ""
172+
${ExitDo}
173+
${EndIf}
174+
${${UN}StrRep} $0 $0 "; " ";" ; Remove ';<space>'
175+
${Loop}
176+
${Do}
177+
${${UN}StrStr} $7 $0 ";;"
178+
${If} $7 == ""
179+
${ExitDo}
180+
${EndIf}
181+
${${UN}StrRep} $0 $0 ";;" ";"
182+
${Loop}
183+
184+
; Remove a leading or trailing semicolon from EnvVar
185+
StrCpy $7 $0 1 0
186+
${If} $7 == ";"
187+
StrCpy $0 $0 "" 1 ; Change ';<EnvVar>' to '<EnvVar>'
188+
${EndIf}
189+
StrLen $6 $0
190+
IntOp $6 $6 - 1
191+
StrCpy $7 $0 1 $6
192+
${If} $7 == ";"
193+
StrCpy $0 $0 $6 ; Change ';<EnvVar>' to '<EnvVar>'
194+
${EndIf}
195+
; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug
196+
${EndIf}
197+
198+
/* Step 3. Remove all instances of the target path/string (even if "A" or "P")
199+
$6 = bool flag (1 = found and removed PathString)
200+
$7 = a string (e.g. path) delimited by semicolon(s)
201+
$8 = entry counter starting at 0
202+
$9 = copy of $0
203+
$R0 = tempChar */
204+
205+
${If} $5 != "" ; If EnvVar is not empty ...
206+
StrCpy $9 $0
207+
StrCpy $0 ""
208+
StrCpy $8 0
209+
StrCpy $6 0
210+
211+
${Do}
212+
${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter
213+
214+
${If} $7 == "" ; If we've run out of entries,
215+
${ExitDo} ; were done
216+
${EndIf} ;
217+
218+
; Remove leading and trailing spaces from this entry (critical step for Action=Remove)
219+
${Do}
220+
StrCpy $R0 $7 1
221+
${If} $R0 != " "
222+
${ExitDo}
223+
${EndIf}
224+
StrCpy $7 $7 "" 1 ; Remove leading space
225+
${Loop}
226+
${Do}
227+
StrCpy $R0 $7 1 -1
228+
${If} $R0 != " "
229+
${ExitDo}
230+
${EndIf}
231+
StrCpy $7 $7 -1 ; Remove trailing space
232+
${Loop}
233+
${If} $7 == $4 ; If string matches, remove it by not appending it
234+
StrCpy $6 1 ; Set 'found' flag
235+
${ElseIf} $7 != $4 ; If string does NOT match
236+
${AndIf} $0 == "" ; and the 1st string being added to $0,
237+
StrCpy $0 $7 ; copy it to $0 without a prepended semicolon
238+
${ElseIf} $7 != $4 ; If string does NOT match
239+
${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0,
240+
StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon
241+
${EndIf} ;
242+
243+
IntOp $8 $8 + 1 ; Bump counter
244+
${Loop} ; Check for duplicates until we run out of paths
245+
${EndIf}
246+
247+
; Step 4: Perform the requested Action
248+
;
249+
${If} $2 != "R" ; If Append or Prepend
250+
${If} $6 == 1 ; And if we found the target
251+
DetailPrint "Target is already present in $1. It will be removed and"
252+
${EndIf}
253+
${If} $0 == "" ; If EnvVar is (now) empty
254+
StrCpy $0 $4 ; just copy PathString to EnvVar
255+
${If} $6 == 0 ; If found flag is either 0
256+
${OrIf} $6 == "" ; or blank (if EnvVarName is empty)
257+
DetailPrint "$1 was empty and has been updated with the target"
258+
${EndIf}
259+
${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty),
260+
StrCpy $0 $0;$4 ; append PathString
261+
${If} $6 == 1
262+
DetailPrint "appended to $1"
263+
${Else}
264+
DetailPrint "Target was appended to $1"
265+
${EndIf}
266+
${Else} ; If Prepend (and EnvVar is not empty),
267+
StrCpy $0 $4;$0 ; prepend PathString
268+
${If} $6 == 1
269+
DetailPrint "prepended to $1"
270+
${Else}
271+
DetailPrint "Target was prepended to $1"
272+
${EndIf}
273+
${EndIf}
274+
${Else} ; If Action = Remove
275+
${If} $6 == 1 ; and we found the target
276+
DetailPrint "Target was found and removed from $1"
277+
${Else}
278+
DetailPrint "Target was NOT found in $1 (nothing to remove)"
279+
${EndIf}
280+
${If} $0 == ""
281+
DetailPrint "$1 is now empty"
282+
${EndIf}
283+
${EndIf}
284+
285+
; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change
286+
;
287+
ClearErrors
288+
${If} $3 == HKLM
289+
WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section
290+
${ElseIf} $3 == HKCU
291+
WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section
292+
${EndIf}
293+
294+
IfErrors 0 +4
295+
MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3"
296+
DetailPrint "Could not write updated $1 to $3"
297+
Goto EnvVarUpdate_Restore_Vars
298+
299+
; "Export" our change
300+
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
301+
302+
EnvVarUpdate_Restore_Vars:
303+
;
304+
; Restore the user's variables and return ResultVar
305+
Pop $R0
306+
Pop $9
307+
Pop $8
308+
Pop $7
309+
Pop $6
310+
Pop $5
311+
Pop $4
312+
Pop $3
313+
Pop $2
314+
Pop $1
315+
Push $0 ; Push my $0 (ResultVar)
316+
Exch
317+
Pop $0 ; Restore his $0
318+
319+
FunctionEnd
320+
321+
!macroend ; EnvVarUpdate UN
322+
!insertmacro EnvVarUpdate ""
323+
!insertmacro EnvVarUpdate "un."
324+
;----------------------------------- EnvVarUpdate end----------------------------------------
325+
326+
!verbose pop
327+
!endif

installer/icon.ico

31.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)