Installer: Consistently use capitalized data type names in the Code section
[msysgit/mtrensch.git] / share / WinGit / install.iss
blob56e47771b34a2b9c0ba38b67e816ec559f71d03b
1 #define APP_NAME 'Git'
2 #define APP_VERSION '%APPVERSION%'
3 #define APP_URL 'http://msysgit.googlecode.com/'
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 InfoBeforeFile=gpl-2.0.rtf
24 PrivilegesRequired=none
25 UninstallDisplayIcon=etc\git.ico
27 ; Cosmetic
28 SetupIconFile=etc\git.ico
29 WizardImageBackColor=clWhite
30 WizardImageStretch=no
31 WizardImageFile=git.bmp
32 WizardSmallImageFile=gitsmall.bmp
34 [Tasks]
35 Name: quicklaunchicon; Description: Create a &Quick Launch icon; GroupDescription: Additional icons:; Flags: checkedonce
36 Name: desktopicon; Description: Create a &Desktop icon; GroupDescription: Additional icons:; Flags: checkedonce
37 Name: shellextension; Description: "Add ""Git Ba&sh Here"""; GroupDescription: Windows Explorer integration:; Flags: checkedonce
38 Name: guiextension; Description: "Add ""Git &GUI Here"""; GroupDescription: Windows Explorer integration:; Flags: checkedonce
39 Name: consolefont; Description: Use TrueType font (required for proper character encoding); GroupDescription: Console properties:; Flags: checkedonce
41 [Files]
42 Source: *; DestDir: {app}; Excludes: \*.bmp, gpl-2.0.rtf, \*.iss, \tmp.*, \bin\*install*; Flags: recursesubdirs replacesameversion
43 Source: ReleaseNotes.rtf; DestDir: {app}; Flags: isreadme replacesameversion
45 [Icons]
46 Name: {group}\Git GUI; Filename: {app}\bin\wish.exe; Parameters: """{app}\libexec\git-core\git-gui"""; WorkingDir: %HOMEDRIVE%%HOMEPATH%; IconFilename: {app}\etc\git.ico
47 Name: {group}\Git Bash; Filename: {syswow64}\cmd.exe; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: %HOMEDRIVE%%HOMEPATH%; IconFilename: {app}\etc\git.ico
48 Name: {group}\Uninstall Git; Filename: {uninstallexe}
49 Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash; Filename: {syswow64}\cmd.exe; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: %HOMEDRIVE%%HOMEPATH%; IconFilename: {app}\etc\git.ico; Tasks: quicklaunchicon
50 Name: {code:GetShellFolder|desktop}\Git Bash; Filename: {syswow64}\cmd.exe; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: %HOMEDRIVE%%HOMEPATH%; IconFilename: {app}\etc\git.ico; Tasks: desktopicon
52 ; Create a special shortcut that does not set a working directory. This is used by "Git Bash.vbs", which in turn is run by the "Git Bash Here" shell extension.
53 Name: {app}\Git Bash; Filename: {syswow64}\cmd.exe; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; IconFilename: {app}\etc\git.ico; Tasks: shellextension
55 [Messages]
56 BeveledLabel={#emit APP_URL}
57 SetupAppTitle={#emit APP_NAME} Setup
58 SetupWindowTitle={#emit APP_NAME} Setup
60 [Registry]
61 Root: HKCU; Subkey: Console; ValueType: string; ValueName: FaceName; ValueData: Lucida Console; Tasks: consolefont
62 Root: HKCU; Subkey: Console; ValueType: dword; ValueName: FontFamily; ValueData: $00000036; Tasks: consolefont
63 Root: HKCU; Subkey: Console; ValueType: dword; ValueName: FontSize; ValueData: $000e0000; Tasks: consolefont
64 Root: HKCU; Subkey: Console; ValueType: dword; ValueName: FontWeight; ValueData: $00000190; Tasks: consolefont
66 Root: HKCU; Subkey: Console\Git Bash; ValueType: string; ValueName: FaceName; ValueData: Lucida Console; Flags: createvalueifdoesntexist
67 Root: HKCU; Subkey: Console\Git Bash; ValueType: dword; ValueName: FontFamily; ValueData: $00000036; Flags: createvalueifdoesntexist
68 Root: HKCU; Subkey: Console\Git Bash; ValueType: dword; ValueName: FontSize; ValueData: $000e0000; Flags: createvalueifdoesntexist
69 Root: HKCU; Subkey: Console\Git Bash; ValueType: dword; ValueName: FontWeight; ValueData: $00000190; Flags: createvalueifdoesntexist
71 [UninstallDelete]
72 Type: files; Name: {app}\bin\git-*.exe
73 Type: files; Name: {app}\libexec\git-core\git-*.exe
74 Type: dirifempty; Name: {app}\home\{username}
75 Type: dirifempty; Name: {app}\home
77 [Code]
78 #include "helpers.inc.iss"
79 #include "putty.inc.iss"
81 function CreateHardLink(lpFileName,lpExistingFileName:String;lpSecurityAttributes:Integer):Boolean;
82 external 'CreateHardLinkA@Kernel32.dll';
84 const
85 // Git Path options.
86 GP_BashOnly = 1;
87 GP_Cmd = 2;
88 GP_CmdTools = 3;
90 // Git SSH options.
91 GS_OpenSSH = 1;
92 GS_Plink = 2;
94 // Git line ending conversion options.
95 GC_LFOnly = 1;
96 GC_CRLFAlways = 2;
97 GC_CRLFCommitAsIs = 3;
99 var
100 // Wizard page and variables for the Path options.
101 PathPage:TWizardPage;
102 RdbPath:array[GP_BashOnly..GP_CmdTools] of TRadioButton;
104 // Wizard page and variables for the SSH options.
105 PuTTYPage:TWizardPage;
106 RdbSSH:array[GS_OpenSSH..GS_Plink] of TRadioButton;
107 EdtPlink:TEdit;
109 // Wizard page and variables for the line ending conversion options.
110 CRLFPage:TWizardPage;
111 RdbCRLF:array[GC_LFOnly..GC_CRLFCommitAsIs] of TRadioButton;
113 procedure BrowseForPuTTYFolder(Sender:TObject);
115 Path:String;
116 begin
117 Path:=ExtractFilePath(EdtPlink.Text);
118 BrowseForFolder('Please select the PuTTY folder:',Path,False);
119 if FileExists(Path+'\TortoisePlink.exe') then begin
120 EdtPlink.Text:=Path+'\TortoisePlink.exe';
121 RdbSSH[GS_Plink].Checked:=True;
122 end else if FileExists(Path+'\plink.exe') then begin
123 EdtPlink.Text:=Path+'\plink.exe';
124 RdbSSH[GS_Plink].Checked:=True;
125 end else begin
126 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError,MB_OK);
127 end;
128 end;
131 Installer code
134 procedure InitializeWizard;
136 PrevPageID:Integer;
137 LblGitBash,LblGitCmd,LblGitCmdTools,LblGitCmdToolsWarn:TLabel;
138 LblOpenSSH,LblPlink:TLabel;
139 PuTTYSessions:TArrayOfString;
140 LblLFOnly,LblCRLFAlways,LblCRLFCommitAsIs:TLabel;
141 BtnPlink:TButton;
142 Data:String;
143 begin
144 PrevPageID:=wpSelectTasks;
147 * Create a custom page for modifying the environment.
150 PathPage:=CreateCustomPage(
151 PrevPageID,
152 'Adjusting your PATH environment',
153 'How would you like to use Git from the command line?'
155 PrevPageID:=PathPage.ID;
157 // 1st choice
158 RdbPath[GP_BashOnly]:=TRadioButton.Create(PathPage);
159 with RdbPath[GP_BashOnly] do begin
160 Parent:=PathPage.Surface;
161 Caption:='Use Git Bash only';
162 Left:=ScaleX(4);
163 Top:=ScaleY(8);
164 Width:=ScaleX(129);
165 Height:=ScaleY(17);
166 Font.Style:=[fsBold];
167 TabOrder:=0;
168 Checked:=True;
169 end;
170 LblGitBash:=TLabel.Create(PathPage);
171 with LblGitBash do begin
172 Parent:=PathPage.Surface;
173 Caption:=
174 'This is the most conservative choice if you are concerned about the stability' + #13 +
175 'of your system. Your PATH will not be modified.';
176 Left:=ScaleX(28);
177 Top:=ScaleY(32);
178 Width:=ScaleX(405);
179 Height:=ScaleY(26);
180 end;
182 // 2nd choice
183 RdbPath[GP_Cmd]:=TRadioButton.Create(PathPage);
184 with RdbPath[GP_Cmd] do begin
185 Parent:=PathPage.Surface;
186 Caption:='Run Git from the Windows Command Prompt';
187 Left:=ScaleX(4);
188 Top:=ScaleY(76);
189 Width:=ScaleX(281);
190 Height:=ScaleY(17);
191 Font.Style:=[fsBold];
192 TabOrder:=1;
193 end;
194 LblGitCmd:=TLabel.Create(PathPage);
195 with LblGitCmd do begin
196 Parent:=PathPage.Surface;
197 Caption:=
198 'This option is considered safe and no conflicts with other tools are known.' + #13 +
199 'Only Git will be added to your PATH. Use this option if you want to use Git' + #13 +
200 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
201 Left:=ScaleX(28);
202 Top:=ScaleY(100);
203 Width:=ScaleX(405);
204 Height:=ScaleY(39);
205 end;
207 // 3rd choice
208 RdbPath[GP_CmdTools]:=TRadioButton.Create(PathPage);
209 with RdbPath[GP_CmdTools] do begin
210 Parent:=PathPage.Surface;
211 Caption:='Run Git and included Unix tools from the Windows Command Prompt';
212 Left:=ScaleX(4);
213 Top:=ScaleY(152);
214 Width:=ScaleX(405);
215 Height:=ScaleY(17);
216 Font.Style:=[fsBold];
217 TabOrder:=2;
218 end;
219 LblGitCmdTools:=TLabel.Create(PathPage);
220 with LblGitCmdTools do begin
221 Parent:=PathPage.Surface;
222 Caption:='Both Git and its accompanying Unix tools will be added to your PATH.';
223 Left:=ScaleX(28);
224 Top:=ScaleY(176);
225 Width:=ScaleX(405);
226 Height:=ScaleY(13);
227 end;
228 LblGitCmdToolsWarn:=TLabel.Create(PathPage);
229 with LblGitCmdToolsWarn do begin
230 Parent:=PathPage.Surface;
231 Caption:=
232 'Warning: This will override Windows tools like find.exe and' + #13 +
233 'sort.exe. Select this option only if you understand the implications.';
234 Left:=ScaleX(28);
235 Top:=ScaleY(192);
236 Width:=ScaleX(376);
237 Height:=ScaleY(26);
238 Font.Color:=255;
239 Font.Style:=[fsBold];
240 end;
242 // Restore the setting chosen during a previous install.
243 Data:=GetPreviousData('Path Option','BashOnly');
244 if Data='BashOnly' then begin
245 RdbPath[GP_BashOnly].Checked:=True;
246 end else if Data='Cmd' then begin
247 RdbPath[GP_Cmd].Checked:=True;
248 end else if Data='CmdTools' then begin
249 RdbPath[GP_CmdTools].Checked:=True;
250 end;
253 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
254 * if at least one PuTTY session is found in the Registry.
257 if RegGetSubkeyNames(HKEY_CURRENT_USER,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions) and (GetArrayLength(PuTTYSessions)>0) then begin
258 PuTTYPage:=CreateCustomPage(
259 PrevPageID,
260 'Choosing the SSH executable',
261 'Which Secure Shell client program would you like Git to use?'
263 PrevPageID:=PuTTYPage.ID;
265 // 1st choice
266 RdbSSH[GS_OpenSSH]:=TRadioButton.Create(PuTTYPage);
267 with RdbSSH[GS_OpenSSH] do begin
268 Parent:=PuTTYPage.Surface;
269 Caption:='Use OpenSSH';
270 Left:=ScaleX(4);
271 Top:=ScaleY(8);
272 Width:=ScaleX(129);
273 Height:=ScaleY(17);
274 Font.Style:=[fsBold];
275 TabOrder:=0;
276 Checked:=True;
277 end;
278 LblOpenSSH:=TLabel.Create(PuTTYPage);
279 with LblOpenSSH do begin
280 Parent:=PuTTYPage.Surface;
281 Caption:=
282 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #13 +
283 'environment variables will not be modified.';
284 Left:=ScaleX(28);
285 Top:=ScaleY(32);
286 Width:=ScaleX(324);
287 Height:=ScaleY(26);
288 end;
290 // 2nd choice
291 RdbSSH[GS_Plink]:=TRadioButton.Create(PuTTYPage);
292 with RdbSSH[GS_Plink] do begin
293 Parent:=PuTTYPage.Surface;
294 Caption:='Use (Tortoise)Plink';
295 Left:=ScaleX(4);
296 Top:=ScaleY(76);
297 Width:=ScaleX(281);
298 Height:=ScaleY(17);
299 Font.Style:=[fsBold];
300 TabOrder:=1;
301 end;
302 LblPlink:=TLabel.Create(PuTTYPage);
303 with LblPlink do begin
304 Parent:=PuTTYPage.Surface;
305 Caption:=
306 'PuTTY sessions were found in your Registry. You may specify the path' + #13 +
307 'to an existing copy of (Tortoise)Plink.exe from the TortoiseSVN/CVS' + #13 +
308 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #13 +
309 'variables will be adjusted to point to the following executable:';
310 Left:=ScaleX(28);
311 Top:=ScaleY(100);
312 Width:=ScaleX(340);
313 Height:=ScaleY(52);
314 end;
315 EdtPlink:=TEdit.Create(PuTTYPage);
316 with EdtPlink do begin
317 Parent:=PuTTYPage.Surface;
318 Text:=GetPuTTYLocation;
319 if not FileExists(Text) then begin
320 Text:='';
321 end;
322 Left:=ScaleX(28);
323 Top:=ScaleY(161);
324 Width:=ScaleX(316);
325 Height:=ScaleY(13);
326 end;
327 BtnPlink:=TButton.Create(PuTTYPage);
328 with BtnPlink do begin
329 Parent:=PuTTYPage.Surface;
330 Caption:='...';
331 OnClick:=@BrowseForPuTTYFolder;
332 Left:=ScaleX(348);
333 Top:=ScaleY(161);
334 Width:=ScaleX(21);
335 Height:=ScaleY(21);
336 end;
338 // Restore the setting chosen during a previous install.
339 Data:=GetPreviousData('SSH Option','OpenSSH');
340 if Data='OpenSSH' then begin
341 RdbSSH[GS_OpenSSH].Checked:=True;
342 end else if Data='Plink' then begin
343 RdbSSH[GS_Plink].Checked:=True;
344 end;
345 end else begin
346 PuTTYPage:=NIL;
347 end;
350 * Create a custom page for the core.autocrlf setting.
353 CRLFPage:=CreateCustomPage(
354 PrevPageID,
355 'Configuring the line ending conversions',
356 'How should Git treat line endings in text files?'
358 PrevPageID:=CRLFPage.ID;
360 // 1st choice
361 RdbCRLF[GC_CRLFAlways]:=TRadioButton.Create(CRLFPage);
362 with RdbCRLF[GC_CRLFAlways] do begin
363 Parent:=CRLFPage.Surface;
364 Caption:='Checkout Windows-style, commit Unix-style line endings';
365 Left:=ScaleX(4);
366 Top:=ScaleY(8);
367 Width:=ScaleX(340);
368 Height:=ScaleY(17);
369 Font.Style:=[fsBold];
370 TabOrder:=0;
371 Checked:=True;
372 end;
373 LblCRLFAlways:=TLabel.Create(CRLFPage);
374 with LblCRLFAlways do begin
375 Parent:=CRLFPage.Surface;
376 Caption:=
377 'Git will convert LF to CRLF when checking out text files. When committing' + #13 +
378 'text files, CRLF will be converted to LF. For cross-platform projects,' + #13 +
379 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
380 Left:=ScaleX(28);
381 Top:=ScaleY(32);
382 Width:=ScaleX(372);
383 Height:=ScaleY(47);
384 end;
386 // 2nd choice
387 RdbCRLF[GC_LFOnly]:=TRadioButton.Create(CRLFPage);
388 with RdbCRLF[GC_LFOnly] do begin
389 Parent:=CRLFPage.Surface;
390 Caption:='Checkout as-is, commit Unix-style line endings';
391 Left:=ScaleX(4);
392 Top:=ScaleY(80);
393 Width:=ScaleX(340);
394 Height:=ScaleY(17);
395 Font.Style:=[fsBold];
396 TabOrder:=1;
397 Checked:=False;
398 end;
399 LblLFOnly:=TLabel.Create(CRLFPage);
400 with LblLFOnly do begin
401 Parent:=CRLFPage.Surface;
402 Caption:=
403 'Git will not perform any conversion when checking out text files. When' + #13 +
404 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #13 +
405 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
406 Left:=ScaleX(28);
407 Top:=ScaleY(104);
408 Width:=ScaleX(372);
409 Height:=ScaleY(47);
410 end;
412 // 3rd choice
413 RdbCRLF[GC_CRLFCommitAsIs]:=TRadioButton.Create(CRLFPage);
414 with RdbCRLF[GC_CRLFCommitAsIs] do begin
415 Parent:=CRLFPage.Surface;
416 Caption:='Checkout as-is, commit as-is';
417 Left:=ScaleX(4);
418 Top:=ScaleY(152);
419 Width:=ScaleX(340);
420 Height:=ScaleY(17);
421 Font.Style:=[fsBold];
422 TabOrder:=2;
423 Checked:=False;
424 end;
425 LblCRLFCommitAsIs:=TLabel.Create(CRLFPage);
426 with LblCRLFCommitAsIs do begin
427 Parent:=CRLFPage.Surface;
428 Caption:=
429 'Git will not perform any conversions when checking out or committing' + #13 +
430 'text files. Choosing this option is not recommended for cross-platform' + #13 +
431 'projects ("core.autocrlf" is set to "false").';
432 Left:=ScaleX(28);
433 Top:=ScaleY(176);
434 Width:=ScaleX(372);
435 Height:=ScaleY(47);
436 end;
438 // Restore the setting chosen during a previous install.
439 Data:=GetPreviousData('CRLF Option','CRLFAlways');
440 if Data='LFOnly' then begin
441 RdbCRLF[GC_LFOnly].Checked:=True;
442 end else if Data='CRLFAlways' then begin
443 RdbCRLF[GC_CRLFAlways].Checked:=True;
444 end else if Data='CRLFCommitAsIs' then begin
445 RdbCRLF[GC_CRLFCommitAsIs].Checked:=True;
446 end;
447 end;
449 function NextButtonClick(CurPageID:Integer):Boolean;
450 begin
451 if (PuTTYPage=NIL) or (CurPageID<>PuTTYPage.ID) then begin
452 Result:=True;
453 Exit;
454 end;
456 Result:=RdbSSH[GS_OpenSSH].Checked or
457 (RdbSSH[GS_Plink].Checked and FileExists(EdtPlink.Text));
459 if not Result then begin
460 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError,MB_OK);
461 end;
462 end;
464 procedure CurStepChanged(CurStep:TSetupStep);
466 AppDir,FileName,Cmd,Msg:String;
467 BuiltIns,EnvPath,EnvHome,EnvSSH:TArrayOfString;
468 Count,i:Longint;
469 IsNTFS:Boolean;
470 FindRec:TFindRec;
471 RootKey:Integer;
472 begin
473 if CurStep<>ssPostInstall then begin
474 Exit;
475 end;
477 AppDir:=ExpandConstant('{app}');
480 Create the built-ins
483 // Load the built-ins from a text file.
484 FileName:=ExpandConstant('{app}\{#emit APP_BUILTINS}');
485 if LoadStringsFromFile(FileName,BuiltIns) then begin
486 // Check if we are running on NTFS.
487 IsNTFS:=False;
488 if SetNTFSCompression(AppDir+'\bin\git.exe',true) then begin
489 IsNTFS:=SetNTFSCompression(AppDir+'\bin\git.exe',false);
490 end;
492 Count:=GetArrayLength(BuiltIns)-1;
494 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
495 for i:=0 to Count do begin
496 FileName:=AppDir+'\bin\'+ChangeFileExt(ExtractFileName(BuiltIns[i]),'');
497 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
498 Log('Line {#emit __LINE__}: Unable to delete script "'+FileName+'", ignoring.');
499 end;
500 end;
502 // Map the built-ins to git.exe.
503 if IsNTFS then begin
504 Log('Line {#emit __LINE__}: Partition seems to be NTFS, trying to create built-in aliases as hard links.');
506 for i:=0 to Count do begin
507 FileName:=AppDir+'\'+BuiltIns[i];
509 // On non-NTFS partitions, create hard links.
510 if (FileExists(FileName) and (not DeleteFile(FileName))) or
511 (not CreateHardLink(FileName,AppDir+'\bin\git.exe',0)) then begin
512 Log('Line {#emit __LINE__}: Unable to create hard link "'+FileName+'", will try to copy files.');
513 IsNTFS:=False;
514 Break;
515 end;
516 end;
518 Log('Line {#emit __LINE__}: Successfully created built-in aliases as hard links.');
519 end;
521 // The fallback is to copy the files.
522 if not IsNTFS then begin
523 Log('Line {#emit __LINE__}: Trying to create built-in aliases as file copies.');
525 for i:=0 to Count do begin
526 FileName:=AppDir+'\'+BuiltIns[i];
528 // On non-NTFS partitions, copy simply the files (overwriting existing ones).
529 if not FileCopy(AppDir+'\bin\git.exe',FileName,false) then begin
530 Msg:='Line {#emit __LINE__}: Unable to create file copy "'+FileName+'".';
531 MsgBox(Msg,mbError,MB_OK);
532 Log(Msg);
533 // This is not a critical error, Git could basically be used without the
534 // aliases for built-ins, so we continue.
535 end;
536 end;
538 Log('Line {#emit __LINE__}: Successfully created built-in aliases as file copies.');
539 end;
541 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
542 if FindFirst(AppDir+'\libexec\git-core\*',FindRec) then begin
543 repeat
544 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
545 FileName:=AppDir+'\bin\'+FindRec.name;
546 if (Pos(FindRec.name,'git.exe')<>1) and FileExists(FileName) and (not DeleteFile(FileName)) then begin
547 Log('Line {#emit __LINE__}: Unable to delete dupe "'+FileName+'", ignoring.');
548 end;
549 end;
550 until not FindNext(FindRec);
551 FindClose(FindRec);
552 end;
553 end else begin
554 Msg:='Line {#emit __LINE__}: Unable to read file "{#emit APP_BUILTINS}".';
555 MsgBox(Msg,mbError,MB_OK);
556 Log(Msg);
557 // This is not a critical error, Git could basically be used without the
558 // aliases for built-ins, so we continue.
559 end;
562 Adapt core.autocrlf
565 if RdbCRLF[GC_LFOnly].checked then begin
566 Cmd:='core.autocrlf input';
567 end else if RdbCRLF[GC_CRLFAlways].checked then begin
568 Cmd:='core.autocrlf true';
569 end else begin
570 Cmd:='core.autocrlf false';
571 end;
572 if not Exec(AppDir + '\bin\git.exe', 'config -f gitconfig ' + Cmd,
573 AppDir + '\etc', SW_HIDE, ewWaitUntilTerminated, i) then begin
574 Msg:='Unable to configure the line ending conversion: ' + Cmd;
575 MsgBox(Msg,mbError,MB_OK);
576 Log(Msg);
577 end;
580 Modify the environment
582 This must happen no later than ssPostInstall to make
583 "ChangesEnvironment=yes" not happend before the change!
586 FileName:=AppDir+'\setup.ini';
588 // Delete GIT_SSH and SVN_SSH if a previous installation set them (this is required for the GS_OpenSSH case).
589 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
590 if (GetArrayLength(EnvSSH)=1) and
591 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',FileName))=0) then begin
592 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
593 Msg:='Line {#emit __LINE__}: Unable to reset GIT_SSH prior to install.';
594 MsgBox(Msg,mbError,MB_OK);
595 Log(Msg);
596 // This is not a critical error, the user can probably fix it manually,
597 // so we continue.
598 end;
599 end;
601 EnvSSH:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn);
602 if (GetArrayLength(EnvSSH)=1) and
603 (CompareStr(EnvSSH[0],GetIniString('Environment','SVN_SSH','',FileName))=0) then begin
604 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn,True,[]) then begin
605 Msg:='Line {#emit __LINE__}: Unable to reset SVN_SSH prior to install.';
606 MsgBox(Msg,mbError,MB_OK);
607 Log(Msg);
608 // This is not a critical error, the user can probably fix it manually,
609 // so we continue.
610 end;
611 end;
613 if (PuTTYPage<>NIL) and RdbSSH[GS_Plink].Checked then begin
614 SetArrayLength(EnvSSH,1);
615 EnvSSH[0]:=EdtPlink.Text;
617 // Set GIT_SSH as specified by the user.
618 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,EnvSSH) then begin
619 Msg:='Line {#emit __LINE__}: Unable to set the GIT_SSH environment variable.';
620 MsgBox(Msg,mbError,MB_OK);
621 Log(Msg);
622 // This is not a critical error, the user can probably fix it manually,
623 // so we continue.
624 end;
626 // Mark that we have changed GIT_SSH by writing its value to a file.
627 if not SetIniString('Environment','GIT_SSH',EnvSSH[0],FileName) then begin
628 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
629 MsgBox(Msg,mbError,MB_OK);
630 Log(Msg);
631 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
632 // so we continue.
633 end;
635 // Set SVN_SSH as specified by the user, but with escaped backslashes and quotes.
636 StringChangeEx(EnvSSH[0],'\','\\',True);
637 EnvSSH[0]:=AddQuotes(EnvSSH[0]);
639 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn,True,EnvSSH) then begin
640 Msg:='Line {#emit __LINE__}: Unable to set the SVN_SSH environment variable.';
641 MsgBox(Msg,mbError,MB_OK);
642 Log(Msg);
643 // This is not a critical error, the user can probably fix it manually,
644 // so we continue.
645 end;
647 // Mark that we have changed SVN_SSH by writing its value to a file.
648 if not SetIniString('Environment','SVN_SSH',EnvSSH[0],FileName) then begin
649 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
650 MsgBox(Msg,mbError,MB_OK);
651 Log(Msg);
652 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
653 // so we continue.
654 end;
655 end;
657 // Get the current user's directories in PATH.
658 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
660 // First, remove the installation directory from PATH in any case.
661 for i:=0 to GetArrayLength(EnvPath)-1 do begin
662 if Pos(AppDir+'\',EnvPath[i]+'\')=1 then begin
663 EnvPath[i]:='';
664 end;
665 end;
667 // Delete HOME if a previous installation modified it.
668 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
669 if (GetArrayLength(EnvHome)=1) and
670 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',FileName))=0) then begin
671 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
672 Msg:='Line {#emit __LINE__}: Unable to reset HOME prior to install.';
673 MsgBox(Msg,mbError,MB_OK);
674 Log(Msg);
675 // This is not a critical error, the user can probably fix it manually,
676 // so we continue.
677 end;
678 end;
680 // Modify the PATH variable as requested by the user.
681 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
682 i:=GetArrayLength(EnvPath);
683 SetArrayLength(EnvPath,i+1);
685 // List \cmd before \bin so \cmd has higher priority and programs in
686 // there will be called in favor of those in \bin.
687 EnvPath[i]:=ExpandConstant('{app}\cmd');
689 if RdbPath[GP_CmdTools].Checked then begin
690 SetArrayLength(EnvPath,i+2);
691 EnvPath[i+1]:=ExpandConstant('{app}\bin');
693 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
694 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
695 i:=GetArrayLength(EnvHome);
696 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
697 SetArrayLength(EnvHome,1);
698 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
699 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,EnvHome) then begin
700 Msg:='Line {#emit __LINE__}: Unable to set the HOME environment variable.';
701 MsgBox(Msg,mbError,MB_OK);
702 Log(Msg);
703 // This is not a critical error, the user can probably fix it manually,
704 // so we continue.
705 end;
707 // Mark that we have changed HOME.
708 if not SetIniString('Environment','HOME',EnvHome[0],FileName) then begin
709 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
710 MsgBox(Msg,mbError,MB_OK);
711 Log(Msg);
712 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
713 // so we continue.
714 end;
715 end;
716 end;
717 end;
719 // Set the current user's PATH directories.
720 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
721 Msg:='Line {#emit __LINE__}: Unable to set the PATH environment variable.';
722 MsgBox(Msg,mbError,MB_OK);
723 Log(Msg);
724 // This is not a critical error, the user can probably fix it manually,
725 // so we continue.
726 end;
729 Create the Windows Explorer shell extensions
732 if IsAdminLoggedOn then begin
733 RootKey:=HKEY_LOCAL_MACHINE;
734 end else begin
735 RootKey:=HKEY_CURRENT_USER;
736 end;
738 if IsTaskSelected('shellextension') then begin
739 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
740 (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','','wscript "'+AppDir+'\Git Bash.vbs" "%1"')) then begin
741 Msg:='Line {#emit __LINE__}: Unable to create "Git Bash Here" shell extension.';
742 MsgBox(Msg,mbError,MB_OK);
743 Log(Msg);
744 // This is not a critical error, the user can probably fix it manually,
745 // so we continue.
746 end;
747 end;
749 if IsTaskSelected('guiextension') then begin
750 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
751 (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command','','"'+AppDir+'\bin\wish.exe" "'+AppDir+'\libexec\git-core\git-gui" "--working-dir" "%1"')) then begin
752 Msg:='Line {#emit __LINE__}: Unable to create "Git GUI Here" shell extension.';
753 MsgBox(Msg,mbError,MB_OK);
754 Log(Msg);
755 // This is not a critical error, the user can probably fix it manually,
756 // so we continue.
757 end;
758 end;
759 end;
761 procedure RegisterPreviousData(PreviousDataKey:Integer);
763 Data:String;
764 begin
765 // Git Path options.
766 Data:='';
767 if RdbPath[GP_BashOnly].Checked then begin
768 Data:='BashOnly';
769 end else if RdbPath[GP_Cmd].Checked then begin
770 Data:='Cmd';
771 end else if RdbPath[GP_CmdTools].Checked then begin
772 Data:='CmdTools';
773 end;
774 SetPreviousData(PreviousDataKey,'Path Option',Data);
776 // Git SSH options.
777 Data:='';
778 if (PuTTYPage=NIL) or RdbSSH[GS_OpenSSH].Checked then begin
779 Data:='OpenSSH';
780 end else if RdbSSH[GS_Plink].Checked then begin
781 Data:='Plink';
782 end;
783 SetPreviousData(PreviousDataKey,'SSH Option',Data);
785 // Line ending conversion options.
786 Data:='';
787 if RdbCRLF[GC_LFOnly].Checked then begin
788 Data:='LFOnly';
789 end else if RdbCRLF[GC_CRLFAlways].Checked then begin
790 Data:='CRLFAlways';
791 end else if RdbCRLF[GC_CRLFCommitAsIs].Checked then begin
792 Data:='CRLFCommitAsIs';
793 end;
794 SetPreviousData(PreviousDataKey,'CRLF Option',Data);
795 end;
798 Uninstaller code
801 function InitializeUninstall:Boolean;
803 FileName,NewName,Msg:String;
804 begin
805 FileName:=ExpandConstant('{app}\bin\ssh-agent.exe');
806 if FileExists(FileName) then begin
807 // Create a temporary copy of the file we try to delete.
808 NewName:=FileName+'.'+IntToStr(1000+Random(9000));
809 Result:=FileCopy(FileName,NewName,True) and DeleteFile(FileName);
811 if not Result then begin
812 Msg:='Line {#emit __LINE__}: Please stop all ssh-agent processes and run uninstall again.';
813 MsgBox(Msg,mbError,MB_OK);
814 Log(Msg);
816 // Clean-up the temporary copy (ignoring any errors).
817 DeleteFile(NewName);
818 end else begin
819 // Clean-up the temporary copy (ignoring any errors).
820 RenameFile(NewName,FileName);
821 end;
822 end else begin
823 Result:=True;
824 end;
825 end;
827 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
829 AppDir,Command,Msg:String;
830 EnvPath,EnvHome,EnvSSH:TArrayOfString;
831 i:Longint;
832 RootKey:Integer;
833 begin
834 if CurUninstallStep<>usUninstall then begin
835 Exit;
836 end;
839 Modify the environment
841 This must happen no later than usUninstall to make
842 "ChangesEnvironment=yes" not happend before the change!
845 AppDir:=ExpandConstant('{app}');
846 Command:=AppDir+'\setup.ini';
848 // Delete the current user's GIT_SSH and SVN_SSH if we set it.
849 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
850 if (GetArrayLength(EnvSSH)=1) and
851 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',Command))=0) then begin
852 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
853 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to GIT_SSH.';
854 MsgBox(Msg,mbError,MB_OK);
855 Log(Msg);
856 // This is not a critical error, the user can probably fix it manually,
857 // so we continue.
858 end;
859 end;
861 EnvSSH:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn);
862 if (GetArrayLength(EnvSSH)=1) and
863 (CompareStr(EnvSSH[0],GetIniString('Environment','SVN_SSH','',Command))=0) then begin
864 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn,True,[]) then begin
865 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to SVN_SSH.';
866 MsgBox(Msg,mbError,MB_OK);
867 Log(Msg);
868 // This is not a critical error, the user can probably fix it manually,
869 // so we continue.
870 end;
871 end;
873 // Get the current user's directories in PATH.
874 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
876 // Remove the installation directory from PATH in any case, even if it
877 // was not added by the installer.
878 for i:=0 to GetArrayLength(EnvPath)-1 do begin
879 if Pos(AppDir+'\',EnvPath[i]+'\')=1 then begin
880 EnvPath[i]:='';
881 end;
882 end;
884 // Reset the current user's directories in PATH.
885 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
886 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to PATH.';
887 MsgBox(Msg,mbError,MB_OK);
888 Log(Msg);
889 // This is not a critical error, the user can probably fix it manually,
890 // so we continue.
891 end;
893 // Reset the current user's HOME if we modified it.
894 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
895 if (GetArrayLength(EnvHome)=1) and
896 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',Command))=0) then begin
897 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
898 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to HOME.';
899 MsgBox(Msg,mbError,MB_OK);
900 Log(Msg);
901 // This is not a critical error, the user can probably fix it manually,
902 // so we continue.
903 end;
904 end;
906 if FileExists(Command) and (not DeleteFile(Command)) then begin
907 Msg:='Line {#emit __LINE__}: Unable to delete file "'+Command+'".';
908 MsgBox(Msg,mbError,MB_OK);
909 Log(Msg);
910 // This is not a critical error, the user can probably fix it manually,
911 // so we continue.
912 end;
915 Delete the Windows Explorer shell extensions
918 if IsAdminLoggedOn then begin
919 RootKey:=HKEY_LOCAL_MACHINE;
920 end else begin
921 RootKey:=HKEY_CURRENT_USER;
922 end;
924 Command:='';
925 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command);
926 if Pos(AppDir,Command)>0 then begin
927 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
928 Msg:='Line {#emit __LINE__}: Unable to remove "Git Bash Here" shell extension.';
929 MsgBox(Msg,mbError,MB_OK);
930 Log(Msg);
931 // This is not a critical error, the user can probably fix it manually,
932 // so we continue.
933 end;
934 end;
936 Command:='';
937 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command);
938 if Pos(AppDir,Command)>0 then begin
939 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
940 Msg:='Line {#emit __LINE__}: Unable to remove "Git GUI Here" shell extension.';
941 MsgBox(Msg,mbError,MB_OK);
942 Log(Msg);
943 // This is not a critical error, the user can probably fix it manually,
944 // so we continue.
945 end;
946 end;
947 end;