Mercurial > hg
comparison contrib/packaging/inno/modpath.iss @ 41847:0f49b56d5d74
inno: replace add_path.exe with a Pascal script
While attempting to build the Inno installer, I was unable to
find a copy of add_path.exe from the source site previously
listed in the docs.
Some quick Googling revealed that achieving this functionality
in native Pascal scripts seems to be preferred these days.
This commit vendors "Modify Path" (fetched from
https://www.legroom.net/software/modpath) and plugs it into
our Inno config file per its instructions.
The existing Inno installer appears to only modify PATH for
the current user (as opposed to at the system level). I've
maintained this behavior with Modify Path. Although it would
be trivial to change or add checkboxes to control the behavior.
I'll leave this as a follow-up.
Differential Revision: https://phab.mercurial-scm.org/D6060
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 28 Feb 2019 12:54:48 -0800 |
parents | |
children | 109315c41d5e |
comparison
equal
deleted
inserted
replaced
41846:765f836a9484 | 41847:0f49b56d5d74 |
---|---|
1 // ---------------------------------------------------------------------------- | |
2 // | |
3 // Inno Setup Ver: 5.4.2 | |
4 // Script Version: 1.4.2 | |
5 // Author: Jared Breland <jbreland@legroom.net> | |
6 // Homepage: http://www.legroom.net/software | |
7 // License: GNU Lesser General Public License (LGPL), version 3 | |
8 // http://www.gnu.org/licenses/lgpl.html | |
9 // | |
10 // Script Function: | |
11 // Allow modification of environmental path directly from Inno Setup installers | |
12 // | |
13 // Instructions: | |
14 // Copy modpath.iss to the same directory as your setup script | |
15 // | |
16 // Add this statement to your [Setup] section | |
17 // ChangesEnvironment=true | |
18 // | |
19 // Add this statement to your [Tasks] section | |
20 // You can change the Description or Flags | |
21 // You can change the Name, but it must match the ModPathName setting below | |
22 // Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked | |
23 // | |
24 // Add the following to the end of your [Code] section | |
25 // ModPathName defines the name of the task defined above | |
26 // ModPathType defines whether the 'user' or 'system' path will be modified; | |
27 // this will default to user if anything other than system is set | |
28 // setArrayLength must specify the total number of dirs to be added | |
29 // Result[0] contains first directory, Result[1] contains second, etc. | |
30 // const | |
31 // ModPathName = 'modifypath'; | |
32 // ModPathType = 'user'; | |
33 // | |
34 // function ModPathDir(): TArrayOfString; | |
35 // begin | |
36 // setArrayLength(Result, 1); | |
37 // Result[0] := ExpandConstant('{app}'); | |
38 // end; | |
39 // #include "modpath.iss" | |
40 // ---------------------------------------------------------------------------- | |
41 | |
42 procedure ModPath(); | |
43 var | |
44 oldpath: String; | |
45 newpath: String; | |
46 updatepath: Boolean; | |
47 pathArr: TArrayOfString; | |
48 aExecFile: String; | |
49 aExecArr: TArrayOfString; | |
50 i, d: Integer; | |
51 pathdir: TArrayOfString; | |
52 regroot: Integer; | |
53 regpath: String; | |
54 | |
55 begin | |
56 // Get constants from main script and adjust behavior accordingly | |
57 // ModPathType MUST be 'system' or 'user'; force 'user' if invalid | |
58 if ModPathType = 'system' then begin | |
59 regroot := HKEY_LOCAL_MACHINE; | |
60 regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; | |
61 end else begin | |
62 regroot := HKEY_CURRENT_USER; | |
63 regpath := 'Environment'; | |
64 end; | |
65 | |
66 // Get array of new directories and act on each individually | |
67 pathdir := ModPathDir(); | |
68 for d := 0 to GetArrayLength(pathdir)-1 do begin | |
69 updatepath := true; | |
70 | |
71 // Modify WinNT path | |
72 if UsingWinNT() = true then begin | |
73 | |
74 // Get current path, split into an array | |
75 RegQueryStringValue(regroot, regpath, 'Path', oldpath); | |
76 oldpath := oldpath + ';'; | |
77 i := 0; | |
78 | |
79 while (Pos(';', oldpath) > 0) do begin | |
80 SetArrayLength(pathArr, i+1); | |
81 pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); | |
82 oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); | |
83 i := i + 1; | |
84 | |
85 // Check if current directory matches app dir | |
86 if pathdir[d] = pathArr[i-1] then begin | |
87 // if uninstalling, remove dir from path | |
88 if IsUninstaller() = true then begin | |
89 continue; | |
90 // if installing, flag that dir already exists in path | |
91 end else begin | |
92 updatepath := false; | |
93 end; | |
94 end; | |
95 | |
96 // Add current directory to new path | |
97 if i = 1 then begin | |
98 newpath := pathArr[i-1]; | |
99 end else begin | |
100 newpath := newpath + ';' + pathArr[i-1]; | |
101 end; | |
102 end; | |
103 | |
104 // Append app dir to path if not already included | |
105 if (IsUninstaller() = false) AND (updatepath = true) then | |
106 newpath := newpath + ';' + pathdir[d]; | |
107 | |
108 // Write new path | |
109 RegWriteStringValue(regroot, regpath, 'Path', newpath); | |
110 | |
111 // Modify Win9x path | |
112 end else begin | |
113 | |
114 // Convert to shortened dirname | |
115 pathdir[d] := GetShortName(pathdir[d]); | |
116 | |
117 // If autoexec.bat exists, check if app dir already exists in path | |
118 aExecFile := 'C:\AUTOEXEC.BAT'; | |
119 if FileExists(aExecFile) then begin | |
120 LoadStringsFromFile(aExecFile, aExecArr); | |
121 for i := 0 to GetArrayLength(aExecArr)-1 do begin | |
122 if IsUninstaller() = false then begin | |
123 // If app dir already exists while installing, skip add | |
124 if (Pos(pathdir[d], aExecArr[i]) > 0) then | |
125 updatepath := false; | |
126 break; | |
127 end else begin | |
128 // If app dir exists and = what we originally set, then delete at uninstall | |
129 if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then | |
130 aExecArr[i] := ''; | |
131 end; | |
132 end; | |
133 end; | |
134 | |
135 // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path | |
136 if (IsUninstaller() = false) AND (updatepath = true) then begin | |
137 SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); | |
138 | |
139 // If uninstalling, write the full autoexec out | |
140 end else begin | |
141 SaveStringsToFile(aExecFile, aExecArr, False); | |
142 end; | |
143 end; | |
144 end; | |
145 end; | |
146 | |
147 // Split a string into an array using passed delimeter | |
148 procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String); | |
149 var | |
150 i: Integer; | |
151 begin | |
152 i := 0; | |
153 repeat | |
154 SetArrayLength(Dest, i+1); | |
155 if Pos(Separator,Text) > 0 then begin | |
156 Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1); | |
157 Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text)); | |
158 i := i + 1; | |
159 end else begin | |
160 Dest[i] := Text; | |
161 Text := ''; | |
162 end; | |
163 until Length(Text)=0; | |
164 end; | |
165 | |
166 | |
167 procedure CurStepChanged(CurStep: TSetupStep); | |
168 var | |
169 taskname: String; | |
170 begin | |
171 taskname := ModPathName; | |
172 if CurStep = ssPostInstall then | |
173 if IsTaskSelected(taskname) then | |
174 ModPath(); | |
175 end; | |
176 | |
177 procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); | |
178 var | |
179 aSelectedTasks: TArrayOfString; | |
180 i: Integer; | |
181 taskname: String; | |
182 regpath: String; | |
183 regstring: String; | |
184 appid: String; | |
185 begin | |
186 // only run during actual uninstall | |
187 if CurUninstallStep = usUninstall then begin | |
188 // get list of selected tasks saved in registry at install time | |
189 appid := '{#emit SetupSetting("AppId")}'; | |
190 if appid = '' then appid := '{#emit SetupSetting("AppName")}'; | |
191 regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1'); | |
192 RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring); | |
193 if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring); | |
194 | |
195 // check each task; if matches modpath taskname, trigger patch removal | |
196 if regstring <> '' then begin | |
197 taskname := ModPathName; | |
198 MPExplode(aSelectedTasks, regstring, ','); | |
199 if GetArrayLength(aSelectedTasks) > 0 then begin | |
200 for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin | |
201 if comparetext(aSelectedTasks[i], taskname) = 0 then | |
202 ModPath(); | |
203 end; | |
204 end; | |
205 end; | |
206 end; | |
207 end; | |
208 | |
209 function NeedRestart(): Boolean; | |
210 var | |
211 taskname: String; | |
212 begin | |
213 taskname := ModPathName; | |
214 if IsTaskSelected(taskname) and not UsingWinNT() then begin | |
215 Result := True; | |
216 end else begin | |
217 Result := False; | |
218 end; | |
219 end; |