WinGit(Inno): Make uninstaller remove directory from PATH
[msysgit.git] / share / WinGit / install.iss
blob0bd353f099efe581b44100c85fc9afdf12e629cb
1 #define APP_NAME 'Git'
2 #define APP_VERSION '%APPVERSION%'
3 #define APP_URL 'http://code.google.com/p/msysgit/'
4 #define APP_BUILTINS 'etc\fileList-builtins.txt'
6 [Setup]
7 ; Compiler-related
8 InternalCompressLevel=max
9 OutputBaseFilename={#emit APP_NAME+'-'+APP_VERSION}
10 OutputDir=%OUTPUTDIR%
11 SolidCompression=yes
13 ; Installer-related
14 AllowNoIcons=yes
15 AppName={#emit APP_NAME}
16 AppPublisherURL={#emit APP_URL}
17 AppVersion={#emit APP_VERSION}
18 AppVerName={#emit APP_NAME+' '+APP_VERSION}
19 ChangesEnvironment=yes
20 DefaultDirName={pf}\{#emit APP_NAME}
21 DefaultGroupName={#emit APP_NAME}
22 DisableReadyPage=yes
23 LicenseFile=gpl-2.0.txt
24 UninstallDisplayIcon=etc\git.ico
26 ; Cosmetic
27 SetupIconFile=etc\git.ico
28 WizardSmallImageFile=git.bmp
30 [Tasks]
31 Name: quicklaunchicon; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: checkedonce
32 Name: desktopicon; Description: "Create a &Desktop icon"; GroupDescription: "Additional icons:"; Flags: checkedonce
33 Name: shellextension; Description: "Add ""Git &Bash Here"""; GroupDescription: "Windows Explorer integration:"; Flags: checkedonce
34 Name: guiextension; Description: "Add ""Git &GUI Here"""; GroupDescription: "Windows Explorer integration:"; Flags: checkedonce
36 [Files]
37 Source: "*"; DestDir: "{app}"; Excludes: "\*.txt, \install.*, \tmp.*, \bin\*install*"; Flags: recursesubdirs
39 [Icons]
40 Name: "{group}\Git GUI"; Filename: "{app}\bin\wish.exe"; Parameters: """{app}\bin\git-gui"""; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"
41 Name: "{group}\Git Bash"; Filename: "{app}\bin\sh.exe"; Parameters: "--login -i"; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"
42 Name: "{group}\Uninstall Git"; Filename: "{uninstallexe}"
43 Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash"; Filename: "{app}\bin\sh.exe"; Parameters: "--login -i"; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"; Tasks: quicklaunchicon
44 Name: "{userdesktop}\Git Bash"; Filename: "{app}\bin\sh.exe"; Parameters: "--login -i"; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"; Tasks: desktopicon
46 [Messages]
47 BeveledLabel={#emit APP_URL}
49 [Registry]
50 Root: HKLM; Subkey: "SOFTWARE\Classes\Directory\shell\git_shell"; ValueType: string; ValueData: "Git &Shell Here"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: shellextension
51 Root: HKLM; Subkey: "SOFTWARE\Classes\Directory\shell\git_shell\command"; ValueType: string; ValueData: "cmd.exe /c ""pushd ""%1"" && ""{app}\bin\sh.exe"" --login -i"""; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: shellextension
52 Root: HKLM; Subkey: "SOFTWARE\Classes\Directory\shell\git_gui"; ValueType: string; ValueData: "Git &GUI Here"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: guiextension
53 Root: HKLM; Subkey: "SOFTWARE\Classes\Directory\shell\git_gui\command"; ValueType: string; ValueData: """{app}\bin\wish.exe"" ""{app}\bin\git-gui"" ""--working-dir"" ""%1"""; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: guiextension
55 [UninstallDelete]
56 Type: files; Name: "{app}\bin\git-*.exe"
57 Type: dirifempty; Name: "{app}\home\{username}"
58 Type: dirifempty; Name: "{app}\home"
60 [Code]
61 var
62 EnvPage:TWizardPage;
63 RdbGitBash,RdbGitCmd,RdbGitCmdTools:TRadioButton;
65 procedure InitializeWizard;
66 var
67 LblGitBash,LblGitCmd,LblGitCmdTools,LblGitCmdToolsWarn:TLabel;
68 begin
69 // Use a mono spaced font in the license dialog. NOTE: This might be too small.
70 WizardForm.LicenseMemo.Font.Name:='Lucida Console';
71 WizardForm.LicenseMemo.Font.Size:=7;
73 // Create a custom page for modifying the environment.
74 EnvPage:=CreateCustomPage(
75 wpInstalling,
76 'Adjusting your PATH environment',
77 'How would you like to use Git from the command line?'
80 // 1st choice
81 RdbGitBash:=TRadioButton.Create(EnvPage);
82 with RdbGitBash do begin
83 Parent:=EnvPage.Surface;
84 Caption:='Use Git Bash only';
85 Left:=ScaleX(4);
86 Top:=ScaleY(8);
87 Width:=ScaleX(129);
88 Height:=ScaleY(17);
89 Font.Style:=[fsBold];
90 TabOrder:=0;
91 Checked:=True;
92 end;
93 LblGitBash:=TLabel.Create(EnvPage);
94 with LblGitBash do begin
95 Parent:=EnvPage.Surface;
96 Caption:=
97 'This is the most conservative choice if you are concerned about the' + #13 +
98 'stability of your system. Your PATH will not be modified.';
99 Left:=ScaleX(28);
100 Top:=ScaleY(32);
101 Width:=ScaleX(324);
102 Height:=ScaleY(26);
103 end;
105 // 2nd choice
106 RdbGitCmd:=TRadioButton.Create(EnvPage);
107 with RdbGitCmd do begin
108 Parent:=EnvPage.Surface;
109 Caption:='Run Git from the Windows Command Prompt';
110 Left:=ScaleX(4);
111 Top:=ScaleY(76);
112 Width:=ScaleX(281);
113 Height:=ScaleY(17);
114 Font.Style:=[fsBold];
115 TabOrder:=1;
116 end;
117 LblGitCmd:=TLabel.Create(EnvPage);
118 with LblGitCmd do begin
119 Parent:=EnvPage.Surface;
120 Caption:=
121 'This option is considered safe and no conflicts with other tools are' + #13 +
122 'known. Only Git will be added to your PATH.';
123 Left:=ScaleX(28);
124 Top:=ScaleY(100);
125 Width:=ScaleX(316);
126 Height:=ScaleY(26);
127 end;
129 // 3rd choice
130 RdbGitCmdTools:=TRadioButton.Create(EnvPage);
131 with RdbGitCmdTools do begin
132 Parent:=EnvPage.Surface;
133 Caption:='Run Git and included Unix tools from the Windows Command Prompt';
134 Left:=ScaleX(4);
135 Top:=ScaleY(152);
136 Width:=ScaleX(393);
137 Height:=ScaleY(17);
138 Font.Style:=[fsBold];
139 TabOrder:=2;
140 end;
141 LblGitCmdTools:=TLabel.Create(EnvPage);
142 with LblGitCmdTools do begin
143 Parent:=EnvPage.Surface;
144 Caption:='Both Git and the Unix tools will be added to your PATH.';
145 Left:=ScaleX(28);
146 Top:=ScaleY(176);
147 Width:=ScaleX(280);
148 Height:=ScaleY(13);
149 end;
150 LblGitCmdToolsWarn:=TLabel.Create(EnvPage);
151 with LblGitCmdToolsWarn do begin
152 Parent:=EnvPage.Surface;
153 Caption:=
154 'Warning: This will override Windows tools like find.exe and' + #13 +
155 'sort.exe. Select this option only if you understand the implications.';
156 Left:=ScaleX(28);
157 Top:=ScaleY(192);
158 Width:=ScaleX(376);
159 Height:=ScaleY(26);
160 Font.Color:=255;
161 Font.Style:=[fsBold];
162 end;
163 end;
165 function GetEnvPathStrings(CurrentUser:Boolean):TArrayOfString;
167 Path:string;
168 i:Longint;
169 p:Integer;
170 begin
171 // See http://www.jrsoftware.org/isfaq.php#env
172 if CurrentUser then begin
173 RegQueryStringValue(HKEY_CURRENT_USER,'Environment','Path',Path);
174 end else begin
175 RegQueryStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment','Path',Path);
176 end;
178 // Make sure we have at least one semicolon.
179 Path:=Path+';';
181 // Split the directories in PATH into an array of strings.
182 i:=0;
183 p:=Pos(';',Path);
184 while p>0 do begin
185 SetArrayLength(Result,i+1);
186 if p>1 then begin
187 Result[i]:=Copy(Path,1,p-1);
188 i:=i+1;
189 end;
190 Path:=Copy(Path,p+1,Length(Path));
191 p:=Pos(';',Path);
192 end;
193 end;
195 procedure SetEnvPathStrings(CurrentUser:Boolean;DirStrings:TArrayOfString);
197 Path:string;
198 i:Longint;
199 begin
200 // Merge all non-empty directory strings into a PATH variable.
201 Path:='';
202 for i:=0 to GetArrayLength(DirStrings)-1 do begin
203 if Length(DirStrings[i])>0 then begin
204 if Length(Path)>0 then begin
205 Path:=Path+';'+DirStrings[i];
206 end else begin
207 Path:=DirStrings[i];
208 end;
209 end;
210 end;
212 // See http://www.jrsoftware.org/isfaq.php#env
213 if CurrentUser then begin
214 RegWriteStringValue(HKEY_CURRENT_USER,'Environment','Path',Path);
215 end else begin
216 RegWriteStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment','Path',Path);
217 end;
218 end;
220 function CreateHardLink(lpFileName,lpExistingFileName:string;lpSecurityAttributes:Integer):Boolean;
221 external 'CreateHardLinkA@Kernel32.dll';
223 procedure CurStepChanged(CurStep:TSetupStep);
225 DirStrings:TArrayOfString;
227 LinkOrCopy:TOutputProgressWizardPage;
228 FileName,AppDir:string;
229 BuiltIns:TArrayOfString;
230 i,Count:Longint;
231 IsNTFS:Boolean;
232 begin
233 AppDir:=ExpandConstant('{app}');
235 if CurStep=ssPostInstall then begin
236 LinkOrCopy:=CreateOutputProgressPage('Creating Build-Ins','Please wait while Setup creates built-in command files.');
237 LinkOrCopy.Show;
239 // Load the built-ins from a text file.
240 FileName:=ExpandConstant('{app}\'+'{#emit APP_BUILTINS}');
241 if not LoadStringsFromFile(FileName,BuiltIns) then begin
242 MsgBox('Unable to read file "{#emit APP_BUILTINS}".', mbError, MB_OK);
243 Exit;
244 end;
246 // Check if we are running on NTFS.
247 IsNTFS:=False;
248 if SetNTFSCompression(AppDir+'\bin\git.exe',true) then begin
249 IsNTFS:=SetNTFSCompression(AppDir+'\bin\git.exe',false);
250 end;
252 Count:=GetArrayLength(BuiltIns)-1;
254 // Map the built-ins to git.exe.
255 if IsNTFS then begin
256 for i:=0 to Count do begin
257 FileName:=AppDir+'\'+BuiltIns[i];
259 // On non-NTFS partitions, create hard links.
260 LinkOrCopy.SetText('Creating hard link...',FileName);
261 LinkOrCopy.SetProgress(i,Count);
262 CreateHardLink(FileName,AppDir+'\bin\git.exe',0);
263 end;
264 end else begin
265 for i:=0 to GetArrayLength(BuiltIns)-1 do begin
266 FileName:=AppDir+'\'+BuiltIns[i];
268 // On non-NTFS partitions, copy simply the files.
269 LinkOrCopy.SetText('Copying file...',FileName);
270 LinkOrCopy.SetProgress(i,Count);
271 FileCopy(AppDir+'\bin\git.exe',FileName,false);
272 end;
273 end;
275 LinkOrCopy.Hide;
276 end else if CurStep=ssDone then begin
277 // Get the current user's directories in PATH.
278 DirStrings:=GetEnvPathStrings(True);
280 // First, remove the installation directory from PATH in any case.
281 for i:=0 to GetArrayLength(DirStrings)-1 do begin
282 if Pos(AppDir,DirStrings[i])=1 then begin
283 DirStrings[i]:='';
284 end;
285 end;
287 // Modify the PATH variable as requested by the user.
288 if RdbGitCmd.Checked then begin
289 i:=GetArrayLength(DirStrings);
290 SetArrayLength(DirStrings,i+1);
291 DirStrings[i]:=ExpandConstant('{app}\cmd');
292 end else if RdbGitCmdTools.Checked then begin
293 i:=GetArrayLength(DirStrings);
294 SetArrayLength(DirStrings,i+2);
295 DirStrings[i]:=ExpandConstant('{app}\cmd');
296 DirStrings[i+1]:=ExpandConstant('{app}\bin');
297 end;
299 // Set the current user's directories in PATH.
300 SetEnvPathStrings(True,DirStrings);
301 end;
302 end;
304 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
306 AppDir:string;
307 DirStrings:TArrayOfString;
308 i:Longint;
309 begin
310 if CurUninstallStep=usDone then begin
311 AppDir:=ExpandConstant('{app}');
313 // Get the current user's directories in PATH.
314 DirStrings:=GetEnvPathStrings(True);
316 // Remove the installation directory from PATH in any case, even if it
317 // was not added by the installer.
318 for i:=0 to GetArrayLength(DirStrings)-1 do begin
319 if Pos(AppDir,DirStrings[i])=1 then begin
320 DirStrings[i]:='';
321 end;
322 end;
324 // Set the current user's directories in PATH.
325 SetEnvPathStrings(True,DirStrings);
326 end;
327 end;