Skip to content

Commit f432e2f

Browse files
committed
Launchers: added support for arbitrary environment variable definition,
using the "environment" section of the winpython.ini configuration file
1 parent c8fb3d0 commit f432e2f

File tree

2 files changed

+290
-26
lines changed

2 files changed

+290
-26
lines changed

portable/include/EnumIni.nsh

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
@FILENAME = EnumIni.nsh
3+
@AUTHORS = Zinthose, Iceman_K
4+
@REVISIONS = zenpoy[http://forums.winamp.com/member.php?u=401997]
5+
@URL = http://nsis.sourceforge.net/mediawiki/index.php?title=Enumerate_INI
6+
*/
7+
!ifndef __EnumIni__
8+
!define __EnumIni__
9+
10+
## Includes
11+
!include "TextFunc.nsh"
12+
!ifndef StrLoc
13+
!include "StrFunc.nsh"
14+
${StrLoc}
15+
!endif
16+
17+
## Macro to remove leading and trailing whitespaces from a string.
18+
## Derived from the function originaly posted by Iceman_K at:
19+
## http://nsis.sourceforge.net/Remove_leading_and_trailing_whitespaces_from_a_string
20+
!ifmacrondef _Trim
21+
!macro _Trim _UserVar _OriginalString
22+
!define Trim_UID ${__LINE__}
23+
24+
Push $R1
25+
Push $R2
26+
Push `${_OriginalString}`
27+
Pop $R1
28+
29+
Loop_${Trim_UID}:
30+
StrCpy $R2 "$R1" 1
31+
StrCmp "$R2" " " TrimLeft_${Trim_UID}
32+
StrCmp "$R2" "$\r" TrimLeft_${Trim_UID}
33+
StrCmp "$R2" "$\n" TrimLeft_${Trim_UID}
34+
StrCmp "$R2" "$\t" TrimLeft_${Trim_UID}
35+
GoTo Loop2_${Trim_UID}
36+
TrimLeft_${Trim_UID}:
37+
StrCpy $R1 "$R1" "" 1
38+
Goto Loop_${Trim_UID}
39+
40+
Loop2_${Trim_UID}:
41+
StrCpy $R2 "$R1" 1 -1
42+
StrCmp "$R2" " " TrimRight_${Trim_UID}
43+
StrCmp "$R2" "$\r" TrimRight_${Trim_UID}
44+
StrCmp "$R2" "$\n" TrimRight_${Trim_UID}
45+
StrCmp "$R2" "$\t" TrimRight_${Trim_UID}
46+
GoTo Done_${Trim_UID}
47+
TrimRight_${Trim_UID}:
48+
StrCpy $R1 "$R1" -1
49+
Goto Loop2_${Trim_UID}
50+
51+
Done_${Trim_UID}:
52+
Pop $R2
53+
Exch $R1
54+
Pop ${_UserVar}
55+
!undef Trim_UID
56+
!macroend
57+
!ifdef Trim
58+
!warning `Trim Macro Previously Defined! Beware of bugs!`
59+
!else
60+
!define Trim `!insertmacro _Trim`
61+
!endif
62+
!endif
63+
64+
## Global variable needed for indexing the enumerations
65+
!ifmacrondef EnumIni_IDX_VAR
66+
!macro EnumIni_IDX_VAR
67+
!ifndef EnumIni_IDX_VAR
68+
VAR /GLOBAL EnumIni_IDX_VAR
69+
!define EnumIni_IDX_VAR $EnumIni_IDX_VAR
70+
!endif
71+
!macroend
72+
!endif
73+
74+
/* ## EnumIniKey ##
75+
Nearly identical in use to the builtin EnumRegKey function, the EnumIniKey macro
76+
allows for enumeration of an existing ini file's sections.
77+
78+
## Example ##
79+
StrCpy $0 0
80+
loop:
81+
${EnumIniKey} $1 `c:\boot.ini` $0
82+
StrCmp $1 "" done
83+
IntOp $0 $0 + 1
84+
MessageBox MB_YESNO|MB_ICONQUESTION "Key=$1$\n$\n$\nMore?" IDYES loop
85+
done:
86+
*/
87+
!ifmacrondef _EnumIniKey
88+
!insertmacro EnumIni_IDX_VAR
89+
!macro _EnumIniKey _UserVar _IniFilePath _Index
90+
!define EnumIniKey_UID ${__LINE__}
91+
ClearErrors
92+
93+
Push $R0
94+
Push $R1
95+
96+
Push `${_IniFilePath}`
97+
Push `${_Index}`
98+
99+
Pop $R1 ; ${_Index}
100+
Pop $R0 ; ${_IniFilePath}
101+
102+
IfFileExists $R0 0 Else_IfFileExists_${EnumIniKey_UID}
103+
StrCpy $EnumIni_IDX_VAR -1
104+
## PATCH Added to Correct 0 length file infinite loop issue discovered by zenpoy
105+
## [http://forums.winamp.com/member.php?u=401997] on January 9th 2012
106+
${LineSum} $R0 $R1
107+
IfErrors Else_IfFileExists_${EnumINIKey_UID}
108+
IntCmp $R1 0 Else_IfFileExists_${EnumINIKey_UID} Else_IfFileExists_${EnumINIKey_UID} 0
109+
## End Revision
110+
${LineFind} $R0 "/NUL" "1:-1" "EnumIniKey_CALLBACK"
111+
IfErrors Else_IfFileExists_${EnumIniKey_UID}
112+
Goto EndIf_FileExists_${EnumIniKey_UID}
113+
Else_IfFileExists_${EnumIniKey_UID}:
114+
StrCpy $R0 ''
115+
SetErrors
116+
EndIf_FileExists_${EnumIniKey_UID}:
117+
118+
Pop $R1
119+
Exch $R0
120+
Pop ${_UserVar}
121+
122+
!undef EnumIniKey_UID
123+
!macroend
124+
!ifndef EnumIniKey
125+
!define EnumIniKey `!insertmacro _EnumIniKey`
126+
!endif
127+
!ifdef __GLOBAL__
128+
!verbose push
129+
!verbose 0
130+
Function EnumIniKey_CALLBACK
131+
!insertmacro _Trim $R9 $R9
132+
133+
StrCmp $R9 '' End
134+
StrCpy $R0 $R9 1
135+
StrCmp $R0 '[' 0 End
136+
IntOp $EnumIni_IDX_VAR $EnumIni_IDX_VAR + 1
137+
IntCmp $R1 $EnumIni_IDX_VAR 0 End End
138+
${StrLoc} $R0 $R9 "]" ">"
139+
IntCmp $R0 0 End
140+
IntOp $R0 $R0 - 1
141+
StrCpy $R0 $R9 $R0 1
142+
Push 'StopLineFind'
143+
Return
144+
End:
145+
StrCpy $R0 ''
146+
Push ''
147+
FunctionEnd
148+
!verbose pop
149+
!else
150+
!Error `An illegal attempt was made to insert the EnumIniValue_CALLBACK function outside the Global namespace!`
151+
!endif
152+
!endif
153+
154+
/* ## EnumIniValue ##
155+
Nearly identical in use to the builtin EnumRegValue function, the EnumIniValue macro
156+
allows for enumeration of an existing ini file section.
157+
158+
## Example ##
159+
StrCpy $0 0
160+
loop:
161+
${EnumIniValue} $1 `c:\boot.ini` `boot loader` $0
162+
StrCmp $1 "" done
163+
IntOp $0 $0 + 1
164+
ReadIniStr $2 `c:\boot.ini` `boot loader` $1
165+
MessageBox MB_YESNO|MB_ICONQUESTION "Value=$1$\n$\t$2$\n$\n$\nMore?" IDYES loop
166+
done:
167+
*/
168+
!ifmacrondef _EnumIniValue
169+
!insertmacro EnumIni_IDX_VAR
170+
!macro _EnumIniValue _UserVar _IniFilePath _Section _Index
171+
!define EnumIniValue_UID ${__LINE__}
172+
ClearErrors
173+
174+
Push $R0
175+
Push $R1
176+
Push $R2
177+
Push $R3
178+
179+
Push `${_IniFilePath}`
180+
Push `${_Section}`
181+
Push `${_Index}`
182+
183+
Pop $R2 ; ${_Index}
184+
Pop $R1 ; ${_Section}
185+
Pop $R0 ; ${_IniFilePath}
186+
187+
IfFileExists $R0 0 Else_IfFileExists_${EnumIniValue_UID}
188+
StrCpy $EnumIni_IDX_VAR -1
189+
${LineFind} $R0 "/NUL" "1:-1" "EnumIniValue_CALLBACK"
190+
IfErrors Else_IfFileExists_${EnumIniValue_UID}
191+
Goto EndIf_FileExists_${EnumIniValue_UID}
192+
Else_IfFileExists_${EnumIniValue_UID}:
193+
StrCpy $R0 ''
194+
SetErrors
195+
EndIf_FileExists_${EnumIniValue_UID}:
196+
197+
Pop $R3
198+
Pop $R2
199+
Pop $R1
200+
Exch $R0
201+
Pop ${_UserVar}
202+
!undef EnumIniValue_UID
203+
!macroend
204+
!ifndef EnumIniValue
205+
!define EnumIniValue `!insertmacro _EnumIniValue`
206+
!endif
207+
!ifdef __GLOBAL__
208+
!verbose push
209+
!verbose 0
210+
Function EnumIniValue_CALLBACK
211+
!insertmacro _Trim $R9 $R9
212+
213+
StrCmp $R9 '' End
214+
StrCpy $R0 $R9 1
215+
StrCmp $R0 ';' End
216+
StrCmp $R0 '#' End
217+
StrCmp $R0 '[' Key
218+
StrCmp $R3 [$R1] 0 End
219+
IntOp $EnumIni_IDX_VAR $EnumIni_IDX_VAR + 1
220+
IntCmp $R2 $EnumIni_IDX_VAR 0 End End
221+
${StrLoc} $R0 $R9 "=" ">"
222+
IntCmp $R0 0 0 0 ValueSet
223+
StrCpy $R0 $R9
224+
ValueSet:
225+
StrCpy $R0 $R9 $R0
226+
Push 'StopLineFind'
227+
Return
228+
Key:
229+
StrCpy $R3 $R9
230+
End:
231+
StrCpy $R0 ''
232+
Push ''
233+
FunctionEnd
234+
!verbose pop
235+
!else
236+
!Error `An illegal attempt was made to insert the EnumIniValue_CALLBACK function outside the Global namespace!`
237+
!endif
238+
!endif
239+
!endif

portable/launcher.nsi

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ OutFile ""
2626
;================================================================
2727

2828
# Standard NSIS plugins
29+
!include "WordFunc.nsh"
2930
!include "FileFunc.nsh"
3031
!include "TextReplace.nsh"
3132

3233
# Custom NSIS plugins
3334
!include "ReplaceInFileWithTextReplace.nsh"
35+
!include "EnumIni.nsh"
3436

3537
SilentInstall silent
3638
AutoCloseWindow true
@@ -53,6 +55,7 @@ end_workdir:
5355
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("WINPYDIR", "${WINPYDIR}").r0'
5456
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("WINPYVER", "${WINPYVER}").r0'
5557

58+
5659
;================================================================
5760
; Settings directory
5861
IfFileExists "$EXEDIR\settings\*.*" 0 end_settings
@@ -73,45 +76,67 @@ end_settings:
7376

7477

7578
; WinPython settings
79+
IfFileExists "$EXEDIR\settings\*.*" 0 winpython_settings_profile
7680
StrCpy $R6 "$EXEDIR\settings\winpython.ini"
81+
Goto winpython_settings_continue
82+
winpython_settings_profile:
83+
StrCpy $R6 "$PROFILE\winpython.ini"
84+
winpython_settings_continue:
7785
IfFileExists $R6 winpython_settings_done
7886
ClearErrors
7987
FileOpen $0 $R6 w
8088
IfErrors winpython_settings_done
89+
FileWrite $0 "[debug]$\r$\nstate = disabled"
90+
FileWrite $0 "$\r$\n"
8191
FileWrite $0 "$\r$\n[environment]"
82-
FileWrite $0 "$\r$\n## Uncomment following lines to override environment variables"
83-
FileWrite $0 "$\r$\n#path = "
84-
FileWrite $0 "$\r$\n#pythonpath = "
85-
FileWrite $0 "$\r$\n#pythonstartup = "
92+
FileWrite $0 "$\r$\n## <?> Uncomment lines to override environment variables"
93+
FileWrite $0 "$\r$\n#PATH = "
94+
FileWrite $0 "$\r$\n#PYTHONPATH = "
95+
FileWrite $0 "$\r$\n#PYTHONSTARTUP = "
8696
FileClose $0
8797
winpython_settings_done:
8898

8999

90-
; PATH
91-
IfFileExists $R6 0 no_path_replacement
92-
ReadINIStr $0 $R6 "environment" path
93-
IfErrors no_path_replacement
94-
StrCpy $R0 $0
95-
Goto set_path
96-
no_path_replacement:
100+
; Debug state
101+
IfFileExists $R6 0 no_debug
102+
ReadINIStr $R7 $R6 "debug" "state"
103+
StrCmp $R7 "" no_debug
104+
StrCmp $R7 "disabled" no_debug
105+
StrCpy $R7 "enabled"
106+
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("WINPYDEBUG", "True").r0'
107+
no_debug:
108+
109+
110+
;================================================================
111+
; Environment variables
97112
ReadEnvStr $R0 "PATH"
98-
set_path:
113+
114+
IfFileExists $R6 0 envvar_done
115+
StrCpy $R9 0
116+
envvar_loop:
117+
${EnumIniValue} $1 $R6 "environment" $R9
118+
StrCmp $1 "" envvar_done
119+
IntOp $R9 $R9 + 1
120+
ReadINIStr $2 $R6 "environment" $1
121+
122+
${StrFilter} $1 "+" "" " " $1 ; Upper case + remove trailing spaces
123+
StrCmp $1 "PATH" found_path
124+
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("$1", "$2").r0'
125+
Goto end_found_path
126+
127+
found_path:
128+
StrCpy $R0 $2
129+
StrCmp $R7 "disabled" end_found_path
130+
MessageBox MB_OK|MB_ICONINFORMATION "Found PATH=$2"
131+
end_found_path:
132+
133+
StrCmp $R7 "disabled" envvar_loop
134+
MessageBox MB_YESNO|MB_ICONQUESTION "$R9: Name='$1'$\nValue='$2'$\n$\n$\nMore?" IDYES envvar_loop
135+
envvar_done:
136+
99137
StrCpy $R0 "${PREPATH};$R0;${POSTPATH}"
100138
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("PATH", R0).r0'
101-
102-
; PYTHONPATH
103-
IfFileExists $R6 0 no_pythonpath_replacement
104-
ReadINIStr $R0 $R6 "environment" pythonpath
105-
IfErrors no_pythonpath_replacement
106-
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("PYTHONPATH", R0).r0'
107-
no_pythonpath_replacement:
108-
109-
; PYTHONSTARTUP
110-
IfFileExists $R6 0 no_pythonstartup_replacement
111-
ReadINIStr $R0 $R6 "environment" pythonstartup
112-
IfErrors no_pythonstartup_replacement
113-
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("PYTHONSTARTUP", R0).r0'
114-
no_pythonstartup_replacement:
139+
;================================================================
115140

116141

117142
; Command line parameters

0 commit comments

Comments
 (0)