WinGit: Fix a trivial indenting issue
[msysgit/mtrensch.git] / share / WinGit / install.iss
blobc4886b8228c587f5047505b1e4db23318d72fb73
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 InfoBeforeFile=gpl-2.0.rtf
24 PrivilegesRequired=none
25 UninstallDisplayIcon=etc\git.ico
27 ; Cosmetic
28 SetupIconFile=etc\git.ico
29 WizardSmallImageFile=git.bmp
31 [Tasks]
32 Name: quicklaunchicon; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: checkedonce
33 Name: desktopicon; Description: "Create a &Desktop icon"; GroupDescription: "Additional icons:"; Flags: checkedonce
34 Name: shellextension; Description: "Add ""Git Ba&sh Here"""; GroupDescription: "Windows Explorer integration:"; Flags: checkedonce
35 Name: guiextension; Description: "Add ""Git &GUI Here"""; GroupDescription: "Windows Explorer integration:"; Flags: checkedonce
37 [Files]
38 Source: "*"; DestDir: "{app}"; Excludes: "\*.bmp, gpl-2.0.rtf, \install.*, \tmp.*, \bin\*install*"; Flags: recursesubdirs
39 Source: ReleaseNotes.rtf; DestDir: "{app}"; Flags: isreadme
41 [Icons]
42 Name: "{group}\Git GUI"; Filename: "{app}\bin\wish.exe"; Parameters: """{app}\libexec\git-core\git-gui"""; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"
43 Name: "{group}\Git Bash"; Filename: "{syswow64}\cmd.exe"; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"
44 Name: "{group}\Uninstall Git"; Filename: "{uninstallexe}"
45 Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash"; Filename: "{syswow64}\cmd.exe"; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"; Tasks: quicklaunchicon
46 Name: "{code:GetShellFolder|desktop}\Git Bash"; Filename: "{syswow64}\cmd.exe"; Parameters: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir: "%USERPROFILE%"; IconFilename: "{app}\etc\git.ico"; Tasks: desktopicon
48 [Messages]
49 BeveledLabel={#emit APP_URL}
50 SetupAppTitle={#emit APP_NAME} Setup
51 SetupWindowTitle={#emit APP_NAME} Setup
53 [UninstallDelete]
54 Type: files; Name: "{app}\bin\git-*.exe"
55 Type: files; Name: "{app}\libexec\git-core\git-*.exe"
56 Type: dirifempty; Name: "{app}\home\{username}"
57 Type: dirifempty; Name: "{app}\home"
59 [Code]
61 Helper methods
64 function GetShellFolder(Param:string):string;
65 begin
66 if IsAdminLoggedOn then begin
67 Param:='{common'+Param+'}';
68 end else begin
69 Param:='{user'+Param+'}';
70 end;
71 Result:=ExpandConstant(Param);
72 end;
74 function CreateHardLink(lpFileName,lpExistingFileName:string;lpSecurityAttributes:Integer):Boolean;
75 external 'CreateHardLinkA@Kernel32.dll';
77 function GetEnvStrings(VarName:string;AllUsers:Boolean):TArrayOfString;
78 var
79 Path:string;
80 i:Longint;
81 p:Integer;
82 begin
83 Path:='';
85 // See http://www.jrsoftware.org/isfaq.php#env
86 if AllUsers then begin
87 // We ignore errors here. The resulting array of strings will be empty.
88 RegQueryStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',VarName,Path);
89 end else begin
90 // We ignore errors here. The resulting array of strings will be empty.
91 RegQueryStringValue(HKEY_CURRENT_USER,'Environment',VarName,Path);
92 end;
94 // Make sure we have at least one semicolon.
95 Path:=Path+';';
97 // Split the directories in PATH into an array of strings.
98 i:=0;
99 SetArrayLength(Result,0);
101 p:=Pos(';',Path);
102 while p>0 do begin
103 SetArrayLength(Result,i+1);
104 if p>1 then begin
105 Result[i]:=Copy(Path,1,p-1);
106 i:=i+1;
107 end;
108 Path:=Copy(Path,p+1,Length(Path));
109 p:=Pos(';',Path);
110 end;
111 end;
113 function SetEnvStrings(VarName:string;AllUsers,DeleteIfEmpty:Boolean;DirStrings:TArrayOfString):Boolean;
115 Path,KeyName:string;
116 i:Longint;
117 begin
118 // Merge all non-empty directory strings into a PATH variable.
119 Path:='';
120 for i:=0 to GetArrayLength(DirStrings)-1 do begin
121 if Length(DirStrings[i])>0 then begin
122 if Length(Path)>0 then begin
123 Path:=Path+';'+DirStrings[i];
124 end else begin
125 Path:=DirStrings[i];
126 end;
127 end;
128 end;
130 // See http://www.jrsoftware.org/isfaq.php#env
131 if AllUsers then begin
132 KeyName:='SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
133 if DeleteIfEmpty and (Length(Path)=0) then begin
134 Result:=(not RegValueExists(HKEY_LOCAL_MACHINE,KeyName,VarName))
135 or RegDeleteValue(HKEY_LOCAL_MACHINE,KeyName,VarName);
136 end else begin
137 Result:=RegWriteStringValue(HKEY_LOCAL_MACHINE,KeyName,VarName,Path);
138 end;
139 end else begin
140 KeyName:='Environment';
141 if DeleteIfEmpty and (Length(Path)=0) then begin
142 Result:=(not RegValueExists(HKEY_CURRENT_USER,KeyName,VarName))
143 or RegDeleteValue(HKEY_CURRENT_USER,KeyName,VarName);
144 end else begin
145 Result:=RegWriteStringValue(HKEY_CURRENT_USER,KeyName,VarName,Path);
146 end;
147 end;
148 end;
150 const
151 PuTTYUninstallKey='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PuTTY_is1';
152 PuTTYPrivateKeyAssoc='PuTTYPrivateKey\shell\open\command';
154 function GetPuTTYLocation:string;
155 begin
156 if RegQueryStringValue(HKEY_LOCAL_MACHINE,PuTTYUninstallKey,'InstallLocation',Result) and DirExists(Result) then begin
157 // C:\Program Files\PuTTY\
158 Exit;
159 end;
160 if RegQueryStringValue(HKEY_CLASSES_ROOT,PuTTYPrivateKeyAssoc,'',Result) then begin
161 // "C:\Program Files\PuTTY\pageant.exe" "%1"
162 Result:=RemoveQuotes(Result);
163 // C:\Program Files\PuTTY\pageant.exe" "%1
164 Result:=ExtractFilePath(Result);
165 // C:\Program Files\PuTTY\
166 if DirExists(Result) then begin
167 Exit;
168 end;
169 end;
170 // Guess something.
171 Result:='C:\Program Files\PuTTY\';
172 end;
174 const
175 // Git Path options.
176 GP_BashOnly = 1;
177 GP_Cmd = 2;
178 GP_CmdTools = 3;
180 // Git SSH options.
181 GS_OpenSSH = 1;
182 GS_PLink = 2;
185 // Wizard page and variables for the Path options.
186 PathPage:TWizardPage;
187 RdbPath:array[GP_BashOnly..GP_CmdTools] of TRadioButton;
189 // Wizard page and variables for the SSH options.
190 PuTTYPage:TWizardPage;
191 RdbSSH:array[GS_OpenSSH..GS_PLink] of TRadioButton;
192 EdtPLink:TEdit;
194 procedure BrowseForPuTTYFolder(Sender:TObject);
196 Path:string;
197 begin
198 Path:=ExtractFilePath(EdtPLink.Text);
199 BrowseForFolder('Please select the PuTTY folder:',Path,False);
200 Path:=Path+'\plink.exe';
201 if FileExists(Path) then begin
202 EdtPLink.Text:=Path;
203 RdbSSH[GS_PLink].Checked:=True;
204 end else begin
205 MsgBox('Please enter a valid path to plink.exe.',mbError,MB_OK);
206 end;
207 end;
210 Installer code
213 procedure InitializeWizard;
215 LblGitBash,LblGitCmd,LblGitCmdTools,LblGitCmdToolsWarn:TLabel;
216 LblOpenSSH,LblPLink:TLabel;
217 BtnPLink:TButton;
218 Data:String;
219 begin
220 // Create a custom page for modifying the environment.
221 PathPage:=CreateCustomPage(
222 wpSelectTasks,
223 'Adjusting your PATH environment',
224 'How would you like to use Git from the command line?'
227 // 1st choice
228 RdbPath[GP_BashOnly]:=TRadioButton.Create(PathPage);
229 with RdbPath[GP_BashOnly] do begin
230 Parent:=PathPage.Surface;
231 Caption:='Use Git Bash only';
232 Left:=ScaleX(4);
233 Top:=ScaleY(8);
234 Width:=ScaleX(129);
235 Height:=ScaleY(17);
236 Font.Style:=[fsBold];
237 TabOrder:=0;
238 Checked:=True;
239 end;
240 LblGitBash:=TLabel.Create(PathPage);
241 with LblGitBash do begin
242 Parent:=PathPage.Surface;
243 Caption:=
244 'This is the most conservative choice if you are concerned about the stability' + #13 +
245 'of your system. Your PATH will not be modified.';
246 Left:=ScaleX(28);
247 Top:=ScaleY(32);
248 Width:=ScaleX(405);
249 Height:=ScaleY(26);
250 end;
252 // 2nd choice
253 RdbPath[GP_Cmd]:=TRadioButton.Create(PathPage);
254 with RdbPath[GP_Cmd] do begin
255 Parent:=PathPage.Surface;
256 Caption:='Run Git from the Windows Command Prompt';
257 Left:=ScaleX(4);
258 Top:=ScaleY(76);
259 Width:=ScaleX(281);
260 Height:=ScaleY(17);
261 Font.Style:=[fsBold];
262 TabOrder:=1;
263 end;
264 LblGitCmd:=TLabel.Create(PathPage);
265 with LblGitCmd do begin
266 Parent:=PathPage.Surface;
267 Caption:=
268 'This option is considered safe and no conflicts with other tools are known.' + #13 +
269 'Only Git will be added to your PATH. Use this option if you want to use Git' + #13 +
270 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
271 Left:=ScaleX(28);
272 Top:=ScaleY(100);
273 Width:=ScaleX(405);
274 Height:=ScaleY(39);
275 end;
277 // 3rd choice
278 RdbPath[GP_CmdTools]:=TRadioButton.Create(PathPage);
279 with RdbPath[GP_CmdTools] do begin
280 Parent:=PathPage.Surface;
281 Caption:='Run Git and included Unix tools from the Windows Command Prompt';
282 Left:=ScaleX(4);
283 Top:=ScaleY(152);
284 Width:=ScaleX(405);
285 Height:=ScaleY(17);
286 Font.Style:=[fsBold];
287 TabOrder:=2;
288 end;
289 LblGitCmdTools:=TLabel.Create(PathPage);
290 with LblGitCmdTools do begin
291 Parent:=PathPage.Surface;
292 Caption:='Both Git and its accompanying Unix tools will be added to your PATH.';
293 Left:=ScaleX(28);
294 Top:=ScaleY(176);
295 Width:=ScaleX(405);
296 Height:=ScaleY(13);
297 end;
298 LblGitCmdToolsWarn:=TLabel.Create(PathPage);
299 with LblGitCmdToolsWarn do begin
300 Parent:=PathPage.Surface;
301 Caption:=
302 'Warning: This will override Windows tools like find.exe and' + #13 +
303 'sort.exe. Select this option only if you understand the implications.';
304 Left:=ScaleX(28);
305 Top:=ScaleY(192);
306 Width:=ScaleX(376);
307 Height:=ScaleY(26);
308 Font.Color:=255;
309 Font.Style:=[fsBold];
310 end;
312 // Restore the setting chosen during a previous install.
313 Data:=GetPreviousData('Path Option','BashOnly');
314 if Data='BashOnly' then begin
315 RdbPath[GP_BashOnly].Checked:=True;
316 end else if Data='Cmd' then begin
317 RdbPath[GP_Cmd].Checked:=True;
318 end else if Data='CmdTools' then begin
319 RdbPath[GP_CmdTools].Checked:=True;
320 end;
322 // Create a custom page for using PuTTY's plink instead of ssh.
323 PuTTYPage:=CreateCustomPage(
324 PathPage.ID,
325 'Choosing the SSH executable',
326 'Which Secure Shell client program would you like Git to use?'
329 // 1st choice
330 RdbSSH[GS_OpenSSH]:=TRadioButton.Create(PuTTYPage);
331 with RdbSSH[GS_OpenSSH] do begin
332 Parent:=PuTTYPage.Surface;
333 Caption:='Use OpenSSH';
334 Left:=ScaleX(4);
335 Top:=ScaleY(8);
336 Width:=ScaleX(129);
337 Height:=ScaleY(17);
338 Font.Style:=[fsBold];
339 TabOrder:=0;
340 Checked:=True;
341 end;
342 LblOpenSSH:=TLabel.Create(PuTTYPage);
343 with LblOpenSSH do begin
344 Parent:=PuTTYPage.Surface;
345 Caption:=
346 'This uses ssh.exe that comes with Git. The GIT_SSH environment' + #13 +
347 'variable will not be modified.';
348 Left:=ScaleX(28);
349 Top:=ScaleY(32);
350 Width:=ScaleX(324);
351 Height:=ScaleY(26);
352 end;
354 // 2nd choice
355 RdbSSH[GS_PLink]:=TRadioButton.Create(PuTTYPage);
356 with RdbSSH[GS_PLink] do begin
357 Parent:=PuTTYPage.Surface;
358 Caption:='Use PLink';
359 Left:=ScaleX(4);
360 Top:=ScaleY(76);
361 Width:=ScaleX(281);
362 Height:=ScaleY(17);
363 Font.Style:=[fsBold];
364 TabOrder:=1;
365 end;
366 LblPLink:=TLabel.Create(PuTTYPage);
367 with LblPLink do begin
368 Parent:=PuTTYPage.Surface;
369 Caption:=
370 'This uses plink.exe from the PuTTY package which needs to be' + #13 +
371 'provided by the user. The GIT_SSH environment variable will be' + #13 +
372 'set to the path to plink.exe as specified below.';
373 Left:=ScaleX(28);
374 Top:=ScaleY(100);
375 Width:=ScaleX(316);
376 Height:=ScaleY(39);
377 end;
378 EdtPLink:=TEdit.Create(PuTTYPage);
379 with EdtPLink do begin
380 Parent:=PuTTYPage.Surface;
381 Text:=GetPuTTYLocation+'plink.exe';
382 if not FileExists(Text) then begin
383 Text:='';
384 end;
385 Left:=ScaleX(28);
386 Top:=ScaleY(148);
387 Width:=ScaleX(316);
388 Height:=ScaleY(13);
389 end;
390 BtnPLink:=TButton.Create(PuTTYPage);
391 with BtnPLink do begin
392 Parent:=PuTTYPage.Surface;
393 Caption:='...';
394 OnClick:=@BrowseForPuTTYFolder;
395 Left:=ScaleX(348);
396 Top:=ScaleY(148);
397 Width:=ScaleX(21);
398 Height:=ScaleY(21);
399 end;
401 // Restore the setting chosen during a previous install.
402 Data:=GetPreviousData('SSH Option','OpenSSH');
403 if Data='OpenSSH' then begin
404 RdbSSH[GS_OpenSSH].Checked:=True;
405 end else if Data='PLink' then begin
406 RdbSSH[GS_PLink].Checked:=True;
407 end;
408 end;
410 function NextButtonClick(CurPageID:Integer):Boolean;
411 begin
412 if CurPageID<>PuTTYPage.ID then begin
413 Result:=True;
414 Exit;
415 end;
417 Result:=RdbSSH[GS_OpenSSH].Checked
418 or (RdbSSH[GS_PLink].Checked and FileExists(EdtPLink.Text));
420 if not Result then begin
421 MsgBox('Please enter a valid path to plink.exe.',mbError,MB_OK);
422 end;
423 end;
425 procedure CurStepChanged(CurStep:TSetupStep);
427 AppDir,FileName,Cmd,Msg:string;
428 BuiltIns,EnvPath,EnvHome,EnvSSH:TArrayOfString;
429 Count,i:Longint;
430 IsNTFS:Boolean;
431 RootKey:Integer;
432 begin
433 if CurStep<>ssPostInstall then begin
434 Exit;
435 end;
437 AppDir:=ExpandConstant('{app}');
440 Create the built-ins
443 // Load the built-ins from a text file.
444 FileName:=ExpandConstant('{app}\'+'{#emit APP_BUILTINS}');
445 if LoadStringsFromFile(FileName,BuiltIns) then begin
446 // Check if we are running on NTFS.
447 IsNTFS:=False;
448 if SetNTFSCompression(AppDir+'\bin\git.exe',true) then begin
449 IsNTFS:=SetNTFSCompression(AppDir+'\bin\git.exe',false);
450 end;
452 Count:=GetArrayLength(BuiltIns)-1;
454 // Delete all scripts as they might have been replaced by built-ins by now.
455 for i:=0 to Count do begin
456 FileName:=ChangeFileExt(AppDir+'\'+BuiltIns[i],'');
457 if (FileExists(FileName) and (not DeleteFile(FileName))) then begin
458 Log('Line {#emit __LINE__}: Unable to delete script "'+FileName+'", ignoring.');
459 end;
460 end;
462 // Map the built-ins to git.exe.
463 if IsNTFS then begin
464 Log('Line {#emit __LINE__}: Partition seems to be NTFS, trying to create built-in aliases as hard links.');
466 for i:=0 to Count do begin
467 FileName:=AppDir+'\'+BuiltIns[i];
469 // On non-NTFS partitions, create hard links.
470 if (FileExists(FileName) and (not DeleteFile(FileName)))
471 or (not CreateHardLink(FileName,AppDir+'\bin\git.exe',0)) then begin
472 Log('Line {#emit __LINE__}: Unable to create hard link "'+FileName+'", will try to copy files.');
473 IsNTFS:=False;
474 Break;
475 end;
476 end;
478 Log('Line {#emit __LINE__}: Successfully created built-in aliases as hard links.');
479 end;
481 // The fallback is to copy the files.
482 if not IsNTFS then begin
483 Log('Line {#emit __LINE__}: Trying to create built-in aliases as file copies.');
485 for i:=0 to Count do begin
486 FileName:=AppDir+'\'+BuiltIns[i];
488 // On non-NTFS partitions, copy simply the files (overwriting existing ones).
489 if not FileCopy(AppDir+'\bin\git.exe',FileName,false) then begin
490 Msg:='Line {#emit __LINE__}: Unable to create file copy "'+FileName+'".';
491 MsgBox(Msg,mbError,MB_OK);
492 Log(Msg);
493 // This is not a critical error, Git could basically be used without the
494 // aliases for built-ins, so we continue.
495 end;
496 end;
498 Log('Line {#emit __LINE__}: Successfully created built-in aliases as file copies.');
499 end;
500 end else begin
501 Msg:='Line {#emit __LINE__}: Unable to read file "{#emit APP_BUILTINS}".';
502 MsgBox(Msg,mbError,MB_OK);
503 Log(Msg);
504 // This is not a critical error, Git could basically be used without the
505 // aliases for built-ins, so we continue.
506 end;
509 Modify the environment
511 This must happen no later than ssPostInstall to make
512 "ChangesEnvironment=yes" not happend before the change!
515 FileName:=AppDir+'\setup.ini';
517 // Delete GIT_SSH if a previous installation modified it.
518 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
519 if (GetArrayLength(EnvSSH)=1) and
520 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',FileName))=0) then begin
521 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
522 Msg:='Line {#emit __LINE__}: Unable to reset GIT_SSH prior to install.';
523 MsgBox(Msg,mbError,MB_OK);
524 Log(Msg);
525 // This is not a critical error, the user can probably fix it manually,
526 // so we continue.
527 end;
528 end;
530 if RdbSSH[GS_PLink].Checked then begin
531 SetArrayLength(EnvSSH,1);
532 EnvSSH[0]:=EdtPLink.Text;
533 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,EnvSSH) then begin
534 Msg:='Line {#emit __LINE__}: Unable to set the GIT_SSH environment variable.';
535 MsgBox(Msg,mbError,MB_OK);
536 Log(Msg);
537 // This is not a critical error, the user can probably fix it manually,
538 // so we continue.
539 end;
541 // Mark that we have changed GIT_SSH.
542 if not SetIniString('Environment','GIT_SSH',EnvSSH[0],FileName) then begin
543 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
544 MsgBox(Msg,mbError,MB_OK);
545 Log(Msg);
546 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
547 // so we continue.
548 end;
549 end;
551 // Get the current user's directories in PATH.
552 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
554 // First, remove the installation directory from PATH in any case.
555 for i:=0 to GetArrayLength(EnvPath)-1 do begin
556 if Pos(AppDir,EnvPath[i])=1 then begin
557 EnvPath[i]:='';
558 end;
559 end;
561 // Delete HOME if a previous installation modified it.
562 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
563 if (GetArrayLength(EnvHome)=1) and
564 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',FileName))=0) then begin
565 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
566 Msg:='Line {#emit __LINE__}: Unable to reset HOME prior to install.';
567 MsgBox(Msg,mbError,MB_OK);
568 Log(Msg);
569 // This is not a critical error, the user can probably fix it manually,
570 // so we continue.
571 end;
572 end;
574 // Modify the PATH variable as requested by the user.
575 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
576 i:=GetArrayLength(EnvPath);
577 SetArrayLength(EnvPath,i+1);
579 // List \cmd before \bin so \cmd has higher priority and programs in
580 // there will be called in favor of those in \bin.
581 EnvPath[i]:=ExpandConstant('{app}\cmd');
583 if RdbPath[GP_CmdTools].Checked then begin
584 SetArrayLength(EnvPath,i+2);
585 EnvPath[i+1]:=ExpandConstant('{app}\bin');
587 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
588 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
589 i:=GetArrayLength(EnvHome);
590 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
591 SetArrayLength(EnvHome,1);
592 EnvHome[0]:=ExpandConstant('{%USERPROFILE}');
593 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,EnvHome) then begin
594 Msg:='Line {#emit __LINE__}: Unable to set the HOME environment variable.';
595 MsgBox(Msg,mbError,MB_OK);
596 Log(Msg);
597 // This is not a critical error, the user can probably fix it manually,
598 // so we continue.
599 end;
601 // Mark that we have changed HOME.
602 if not SetIniString('Environment','HOME',EnvHome[0],FileName) then begin
603 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
604 MsgBox(Msg,mbError,MB_OK);
605 Log(Msg);
606 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
607 // so we continue.
608 end;
609 end;
610 end;
611 end;
613 // Set the current user's PATH directories.
614 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
615 Msg:='Line {#emit __LINE__}: Unable to set the PATH environment variable.';
616 MsgBox(Msg,mbError,MB_OK);
617 Log(Msg);
618 // This is not a critical error, the user can probably fix it manually,
619 // so we continue.
620 end;
623 Create the Windows Explorer shell extensions
626 if IsAdminLoggedOn then begin
627 RootKey:=HKEY_LOCAL_MACHINE;
628 end else begin
629 RootKey:=HKEY_CURRENT_USER;
630 end;
632 if IsTaskSelected('shellextension') then begin
633 Cmd:=ExpandConstant('"{syswow64}\cmd.exe"');
634 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here'))
635 or (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd+' /c "pushd "%1" && "'+AppDir+'\bin\sh.exe" --login -i"')) then begin
636 Msg:='Line {#emit __LINE__}: Unable to create "Git Bash Here" shell extension.';
637 MsgBox(Msg,mbError,MB_OK);
638 Log(Msg);
639 // This is not a critical error, the user can probably fix it manually,
640 // so we continue.
641 end;
642 end;
644 if IsTaskSelected('guiextension') then begin
645 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here'))
646 or (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
647 Msg:='Line {#emit __LINE__}: Unable to create "Git GUI Here" shell extension.';
648 MsgBox(Msg,mbError,MB_OK);
649 Log(Msg);
650 // This is not a critical error, the user can probably fix it manually,
651 // so we continue.
652 end;
653 end;
654 end;
656 procedure RegisterPreviousData(PreviousDataKey:Integer);
658 Data:string;
659 begin
660 // Git Path options.
661 Data:='';
662 if RdbPath[GP_BashOnly].Checked then begin
663 Data:='BashOnly';
664 end else if RdbPath[GP_Cmd].Checked then begin
665 Data:='Cmd';
666 end else if RdbPath[GP_CmdTools].Checked then begin
667 Data:='CmdTools';
668 end;
669 SetPreviousData(PreviousDataKey,'Path Option',Data);
671 // Git SSH options.
672 Data:='';
673 if RdbSSH[GS_OpenSSH].Checked then begin
674 Data:='OpenSSH';
675 end else if RdbSSH[GS_PLink].Checked then begin
676 Data:='PLink';
677 end;
678 SetPreviousData(PreviousDataKey,'SSH Option',Data);
679 end;
682 Uninstaller code
685 function InitializeUninstall:Boolean;
687 FileName,NewName,Msg:string;
688 begin
689 FileName:=ExpandConstant('{app}')+'\bin\ssh-agent.exe';
690 if FileExists(FileName) then begin
691 // Create a temporary copy of the file we try to delete.
692 NewName:=FileName+'.'+IntToStr(1000+Random(9000));
693 Result:=FileCopy(FileName,NewName,True) and DeleteFile(FileName);
695 if not Result then begin
696 Msg:='Line {#emit __LINE__}: Please stop all ssh-agent processes and run uninstall again.';
697 MsgBox(Msg,mbError,MB_OK);
698 Log(Msg);
700 // Clean-up the temporary copy (ignoring any errors).
701 DeleteFile(NewName);
702 end else begin
703 // Clean-up the temporary copy (ignoring any errors).
704 RenameFile(NewName,FileName);
705 end;
706 end else begin
707 Result:=True;
708 end;
709 end;
711 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
713 AppDir,Command,Msg:string;
714 EnvPath,EnvHome,EnvSSH:TArrayOfString;
715 i:Longint;
716 RootKey:Integer;
717 begin
718 if CurUninstallStep<>usUninstall then begin
719 Exit;
720 end;
723 Modify the environment
725 This must happen no later than usUninstall to make
726 "ChangesEnvironment=yes" not happend before the change!
729 AppDir:=ExpandConstant('{app}');
730 Command:=AppDir+'\setup.ini';
732 // Reset the current user's GIT_SSH if we modified it.
733 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
734 if (GetArrayLength(EnvSSH)=1) and
735 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',Command))=0) then begin
736 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
737 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to GIT_SSH.';
738 MsgBox(Msg,mbError,MB_OK);
739 Log(Msg);
740 // This is not a critical error, the user can probably fix it manually,
741 // so we continue.
742 end;
743 end;
745 // Get the current user's directories in PATH.
746 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
748 // Remove the installation directory from PATH in any case, even if it
749 // was not added by the installer.
750 for i:=0 to GetArrayLength(EnvPath)-1 do begin
751 if Pos(AppDir,EnvPath[i])=1 then begin
752 EnvPath[i]:='';
753 end;
754 end;
756 // Reset the current user's directories in PATH.
757 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
758 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to PATH.';
759 MsgBox(Msg,mbError,MB_OK);
760 Log(Msg);
761 // This is not a critical error, the user can probably fix it manually,
762 // so we continue.
763 end;
765 // Reset the current user's HOME if we modified it.
766 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
767 if (GetArrayLength(EnvHome)=1) and
768 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',Command))=0) then begin
769 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
770 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to HOME.';
771 MsgBox(Msg,mbError,MB_OK);
772 Log(Msg);
773 // This is not a critical error, the user can probably fix it manually,
774 // so we continue.
775 end;
776 end;
778 if (FileExists(Command) and (not DeleteFile(Command))) then begin
779 Msg:='Line {#emit __LINE__}: Unable to delete file "'+Command+'".';
780 MsgBox(Msg,mbError,MB_OK);
781 Log(Msg);
782 // This is not a critical error, the user can probably fix it manually,
783 // so we continue.
784 end;
787 Delete the Windows Explorer shell extensions
790 if IsAdminLoggedOn then begin
791 RootKey:=HKEY_LOCAL_MACHINE;
792 end else begin
793 RootKey:=HKEY_CURRENT_USER;
794 end;
796 Command:='';
797 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command);
798 if Pos(AppDir,Command)>0 then begin
799 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
800 Msg:='Line {#emit __LINE__}: Unable to remove "Git Bash Here" shell extension.';
801 MsgBox(Msg,mbError,MB_OK);
802 Log(Msg);
803 // This is not a critical error, the user can probably fix it manually,
804 // so we continue.
805 end;
806 end;
808 Command:='';
809 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command);
810 if Pos(AppDir,Command)>0 then begin
811 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
812 Msg:='Line {#emit __LINE__}: Unable to remove "Git GUI Here" shell extension.';
813 MsgBox(Msg,mbError,MB_OK);
814 Log(Msg);
815 // This is not a critical error, the user can probably fix it manually,
816 // so we continue.
817 end;
818 end;
819 end;