1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
#! stdtmpl | standard
#proc GenerateInnoSetup(c: TConfigData): string =
# result = ""
; Default Template for NimInst
[Setup]
AppName=$c.displayName
AppVerName=$c.displayName $c.version
DefaultDirName={code:GiveMeAPath|$c.displayName}
DefaultGroupName=$c.displayName
AllowNoIcons=yes
LicenseFile=${expandFilename(c.license)}
OutputBaseFilename=${c.name}_${c.version}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none
ChangesEnvironment=yes
[Languages]
Name: english; MessagesFile: compiler:Default.isl
[Files]
#for i in low(TFileCategory)..fcWindows:
# for f in items(c.cat[i]):
Source: ${expandFilename(f)}; DestDir: {app}\${splitFile(f).dir}; Flags: ignoreversion
# end for
#end for
[Icons]
#if c.app == appConsole:
Name: {group}\Console for $c.displayName; Filename: {cmd}
#else:
Name: {group}\$c.displayName; Filename: {app}\${c.name}.exe
#end if
#for f in items(c.cat[fcDocStart]):
Name: {group}\Documentation; Filename: {app}\$f
#end for
Name: {group}\{cm:UninstallProgram,$c.displayName}; Filename: {uninstallexe}
#if c.binPaths.len > 0:
[Tasks]
Name: modifypath; Description: &Add $c.displayName to your system path (if not in path already);
#end if
[Code]
function GiveMeAPath(const DefaultPathName: string): string;
begin
if IsAdminLoggedOn then Result := ExpandConstant('{pf}')
else Result := ExpandConstant('{userdocs}');
Result := Result + '\' + DefaultPathName;
end;
#if c.binPaths.len > 0:
// ----------------------------------------------------------------------------
//
// Inno Setup Ver: 5.2.1
// Script Version: 1.3.1
// Author: Jared Breland <jbreland@legroom.net>
// Homepage: http://www.legroom.net/software
//
// Script Function:
// Enable modification of system path directly from Inno Setup installers
function ModPathDir(): TArrayOfString;
begin
setArrayLength(result, $c.binPaths.len);
#var i = 0
#for b in items(c.binPaths):
result[$i] := ExpandConstant('{app}') + '\$b';
#inc(i)
#end for
end;
procedure ModPath();
var
oldpath, newpath, aExecFile: String;
pathArr, aExecArr, pathdir: TArrayOfString;
i, d: Integer;
begin
// Get array of new directories and act on each individually
pathdir := ModPathDir();
for d := 0 to GetArrayLength(pathdir)-1 do begin
// Modify WinNT path
if UsingWinNT() then begin
// Get current path, split into an array
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', oldpath);
oldpath := oldpath + ';';
i := 0;
while (Pos(';', oldpath) > 0) do begin
SetArrayLength(pathArr, i+1);
pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
i := i + 1;
// Check if current directory matches app dir
if pathdir[d] = pathArr[i-1] then begin
// if uninstalling, remove dir from path
if IsUninstaller() then continue
// if installing, abort because dir was already in path
else abort;
end;
// Add current directory to new path
if i = 1 then newpath := pathArr[i-1]
else newpath := newpath + ';' + pathArr[i-1];
end;
// Append app dir to path if not already included
if not IsUninstaller() then
newpath := newpath + ';' + pathdir[d];
// Write new path
RegWriteStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', newpath);
end
else begin
// Modify Win9x path
// Convert to shortened dirname
pathdir[d] := GetShortName(pathdir[d]);
// If autoexec.bat exists, check if app dir already exists in path
aExecFile := 'C:\AUTOEXEC.BAT';
if FileExists(aExecFile) then begin
LoadStringsFromFile(aExecFile, aExecArr);
for i := 0 to GetArrayLength(aExecArr)-1 do begin
if not IsUninstaller() then begin
// If app dir already exists while installing, abort add
if (Pos(pathdir[d], aExecArr[i]) > 0) then
abort;
end
else begin
// If app dir exists and = what we originally set,
// then delete at uninstall
if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
aExecArr[i] := '';
end;
end;
end;
// If app dir not found, or autoexec.bat didn't exist, then
// (create and) append to current path
if not IsUninstaller() then begin
SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d],
True);
end
else begin
// If uninstalling, write the full autoexec out
SaveStringsToFile(aExecFile, aExecArr, False);
end;
end;
// Write file to flag modifypath was selected
// Workaround since IsTaskSelected() cannot be called at uninstall and
// AppName and AppId cannot be "read" in Code section
if not IsUninstaller() then
SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt',
WizardSelectedTasks(False), False);
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then begin
if IsTaskSelected('modifypath') then
ModPath();
end
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
appdir, selectedTasks: String;
begin
appdir := ExpandConstant('{app}');
if CurUninstallStep = usUninstall then begin
if LoadStringFromFile(appdir + '\uninsTasks.txt', selectedTasks) then
if Pos('modifypath', selectedTasks) > 0 then
ModPath();
DeleteFile(appdir + '\uninsTasks.txt')
end;
end;
function NeedRestart(): Boolean;
begin
result := IsTaskSelected('modifypath') and not UsingWinNT()
end;
#end if
|