WinGit: Optionally use a user provided PLink (PuTTY) instead of OpenSSH
[msysgit/mtrensch.git] / share / WinGit / install.iss
blob7cbbed4ac211c1cc1eb3ed7c55ebc04932fe1b3f
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}\bin\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: dirifempty; Name: "{app}\home\{username}"
56 Type: dirifempty; Name: "{app}\home"
58 [Code]
60 Helper methods
63 function GetShellFolder(Param:string):string;
64 begin
65 if IsAdminLoggedOn then begin
66 Param:='{common'+Param+'}';
67 end else begin
68 Param:='{user'+Param+'}';
69 end;
70 Result:=ExpandConstant(Param);
71 end;
73 function CreateHardLink(lpFileName,lpExistingFileName:string;lpSecurityAttributes:Integer):Boolean;
74 external 'CreateHardLinkA@Kernel32.dll';
76 function GetEnvStrings(VarName:string;AllUsers:Boolean):TArrayOfString;
77 var
78 Path:string;
79 i:Longint;
80 p:Integer;
81 begin
82 Path:='';
84 // See http://www.jrsoftware.org/isfaq.php#env
85 if AllUsers then begin
86 // We ignore errors here. The resulting array of strings will be empty.
87 RegQueryStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',VarName,Path);
88 end else begin
89 // We ignore errors here. The resulting array of strings will be empty.
90 RegQueryStringValue(HKEY_CURRENT_USER,'Environment',VarName,Path);
91 end;
93 // Make sure we have at least one semicolon.
94 Path:=Path+';';
96 // Split the directories in PATH into an array of strings.
97 i:=0;
98 SetArrayLength(Result,0);
100 p:=Pos(';',Path);
101 while p>0 do begin
102 SetArrayLength(Result,i+1);
103 if p>1 then begin
104 Result[i]:=Copy(Path,1,p-1);
105 i:=i+1;
106 end;
107 Path:=Copy(Path,p+1,Length(Path));
108 p:=Pos(';',Path);
109 end;
110 end;
112 function SetEnvStrings(VarName:string;AllUsers,DeleteIfEmpty:Boolean;DirStrings:TArrayOfString):Boolean;
114 Path,KeyName:string;
115 i:Longint;
116 begin
117 // Merge all non-empty directory strings into a PATH variable.
118 Path:='';
119 for i:=0 to GetArrayLength(DirStrings)-1 do begin
120 if Length(DirStrings[i])>0 then begin
121 if Length(Path)>0 then begin
122 Path:=Path+';'+DirStrings[i];
123 end else begin
124 Path:=DirStrings[i];
125 end;
126 end;
127 end;
129 // See http://www.jrsoftware.org/isfaq.php#env
130 if AllUsers then begin
131 KeyName:='SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
132 if DeleteIfEmpty and (Length(Path)=0) then begin
133 Result:=(not RegValueExists(HKEY_LOCAL_MACHINE,KeyName,VarName))
134 or RegDeleteValue(HKEY_LOCAL_MACHINE,KeyName,VarName);
135 end else begin
136 Result:=RegWriteStringValue(HKEY_LOCAL_MACHINE,KeyName,VarName,Path);
137 end;
138 end else begin
139 KeyName:='Environment';
140 if DeleteIfEmpty and (Length(Path)=0) then begin
141 Result:=(not RegValueExists(HKEY_CURRENT_USER,KeyName,VarName))
142 or RegDeleteValue(HKEY_CURRENT_USER,KeyName,VarName);
143 end else begin
144 Result:=RegWriteStringValue(HKEY_CURRENT_USER,KeyName,VarName,Path);
145 end;
146 end;
147 end;
149 const
150 PuTTYUninstallKey='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PuTTY_is1';
151 PuTTYPrivateKeyAssoc='PuTTYPrivateKey\shell\open\command';
153 function GetPuTTYLocation:string;
154 begin
155 if RegQueryStringValue(HKEY_LOCAL_MACHINE,PuTTYUninstallKey,'InstallLocation',Result) and DirExists(Result) then begin
156 // C:\Program Files\PuTTY\
157 Exit;
158 end;
159 if RegQueryStringValue(HKEY_CLASSES_ROOT,PuTTYPrivateKeyAssoc,'',Result) then begin
160 // "C:\Program Files\PuTTY\pageant.exe" "%1"
161 Result:=RemoveQuotes(Result);
162 // C:\Program Files\PuTTY\pageant.exe" "%1
163 Result:=ExtractFilePath(Result);
164 // C:\Program Files\PuTTY\
165 if DirExists(Result) then begin
166 Exit;
167 end;
168 end;
169 // Guess something.
170 Result:='C:\Program Files\PuTTY\';
171 end;
174 EnvPage,PuTTYPage:TWizardPage;
175 RdbGitBash,RdbGitCmd,RdbGitCmdTools:TRadioButton;
176 RdbOpenSSH,RdbPLink:TRadioButton;
177 EdtPLink:TEdit;
179 procedure BrowseForPuTTYFolder(Sender:TObject);
181 Path:string;
182 begin
183 Path:=ExtractFilePath(EdtPLink.Text);
184 BrowseForFolder('Please select the PuTTY folder:',Path,False);
185 Path:=Path+'\plink.exe';
186 if FileExists(Path) then begin
187 EdtPLink.Text:=Path;
188 RdbPLink.Checked:=True;
189 end else begin
190 MsgBox('Please enter a valid path to plink.exe.',mbError,MB_OK);
191 end;
192 end;
195 Installer code
198 procedure InitializeWizard;
200 LblGitBash,LblGitCmd,LblGitCmdTools,LblGitCmdToolsWarn:TLabel;
201 LblOpenSSH,LblPLink:TLabel;
202 BtnPLink:TButton;
203 begin
204 // Create a custom page for modifying the environment.
205 EnvPage:=CreateCustomPage(
206 wpSelectTasks,
207 'Adjusting your PATH environment',
208 'How would you like to use Git from the command line?'
211 // 1st choice
212 RdbGitBash:=TRadioButton.Create(EnvPage);
213 with RdbGitBash do begin
214 Parent:=EnvPage.Surface;
215 Caption:='Use Git Bash only';
216 Left:=ScaleX(4);
217 Top:=ScaleY(8);
218 Width:=ScaleX(129);
219 Height:=ScaleY(17);
220 Font.Style:=[fsBold];
221 TabOrder:=0;
222 Checked:=True;
223 end;
224 LblGitBash:=TLabel.Create(EnvPage);
225 with LblGitBash do begin
226 Parent:=EnvPage.Surface;
227 Caption:=
228 'This is the most conservative choice if you are concerned about the' + #13 +
229 'stability of your system. Your PATH will not be modified.';
230 Left:=ScaleX(28);
231 Top:=ScaleY(32);
232 Width:=ScaleX(324);
233 Height:=ScaleY(26);
234 end;
236 // 2nd choice
237 RdbGitCmd:=TRadioButton.Create(EnvPage);
238 with RdbGitCmd do begin
239 Parent:=EnvPage.Surface;
240 Caption:='Run Git from the Windows Command Prompt';
241 Left:=ScaleX(4);
242 Top:=ScaleY(76);
243 Width:=ScaleX(281);
244 Height:=ScaleY(17);
245 Font.Style:=[fsBold];
246 TabOrder:=1;
247 end;
248 LblGitCmd:=TLabel.Create(EnvPage);
249 with LblGitCmd do begin
250 Parent:=EnvPage.Surface;
251 Caption:=
252 'This option is considered safe and no conflicts with other tools are' + #13 +
253 'known. Only Git will be added to your PATH.';
254 Left:=ScaleX(28);
255 Top:=ScaleY(100);
256 Width:=ScaleX(316);
257 Height:=ScaleY(26);
258 end;
260 // 3rd choice
261 RdbGitCmdTools:=TRadioButton.Create(EnvPage);
262 with RdbGitCmdTools do begin
263 Parent:=EnvPage.Surface;
264 Caption:='Run Git and included Unix tools from the Windows Command Prompt';
265 Left:=ScaleX(4);
266 Top:=ScaleY(152);
267 Width:=ScaleX(405);
268 Height:=ScaleY(17);
269 Font.Style:=[fsBold];
270 TabOrder:=2;
271 end;
272 LblGitCmdTools:=TLabel.Create(EnvPage);
273 with LblGitCmdTools do begin
274 Parent:=EnvPage.Surface;
275 Caption:='Both Git and the Unix tools will be added to your PATH.';
276 Left:=ScaleX(28);
277 Top:=ScaleY(176);
278 Width:=ScaleX(280);
279 Height:=ScaleY(13);
280 end;
281 LblGitCmdToolsWarn:=TLabel.Create(EnvPage);
282 with LblGitCmdToolsWarn do begin
283 Parent:=EnvPage.Surface;
284 Caption:=
285 'Warning: This will override Windows tools like find.exe and' + #13 +
286 'sort.exe. Select this option only if you understand the implications.';
287 Left:=ScaleX(28);
288 Top:=ScaleY(192);
289 Width:=ScaleX(376);
290 Height:=ScaleY(26);
291 Font.Color:=255;
292 Font.Style:=[fsBold];
293 end;
295 // Create a custom page for using PuTTY's plink instead of ssh.
296 PuTTYPage:=CreateCustomPage(
297 EnvPage.ID,
298 'Choosing the SSH executable',
299 'Which Secure Shell client program would you like Git to use?'
302 // 1st choice
303 RdbOpenSSH:=TRadioButton.Create(PuTTYPage);
304 with RdbOpenSSH do begin
305 Parent:=PuTTYPage.Surface;
306 Caption:='Use OpenSSH';
307 Left:=ScaleX(4);
308 Top:=ScaleY(8);
309 Width:=ScaleX(129);
310 Height:=ScaleY(17);
311 Font.Style:=[fsBold];
312 TabOrder:=0;
313 Checked:=True;
314 end;
315 LblOpenSSH:=TLabel.Create(PuTTYPage);
316 with LblOpenSSH do begin
317 Parent:=PuTTYPage.Surface;
318 Caption:=
319 'This uses ssh.exe that comes with Git. The GIT_SSH environment' + #13 +
320 'variable will not be modified.';
321 Left:=ScaleX(28);
322 Top:=ScaleY(32);
323 Width:=ScaleX(324);
324 Height:=ScaleY(26);
325 end;
327 // 2nd choice
328 RdbPLink:=TRadioButton.Create(PuTTYPage);
329 with RdbPLink do begin
330 Parent:=PuTTYPage.Surface;
331 Caption:='Use PLink';
332 Left:=ScaleX(4);
333 Top:=ScaleY(76);
334 Width:=ScaleX(281);
335 Height:=ScaleY(17);
336 Font.Style:=[fsBold];
337 TabOrder:=1;
338 end;
339 LblPLink:=TLabel.Create(PuTTYPage);
340 with LblPLink do begin
341 Parent:=PuTTYPage.Surface;
342 Caption:=
343 'This uses plink.exe from the PuTTY package which needs to be' + #13 +
344 'provided by the user. The GIT_SSH environment variable will be' + #13 +
345 'set to the path to plink.exe as specified below.';
346 Left:=ScaleX(28);
347 Top:=ScaleY(100);
348 Width:=ScaleX(316);
349 Height:=ScaleY(39);
350 end;
351 EdtPLink:=TEdit.Create(PuTTYPage);
352 with EdtPLink do begin
353 Parent:=PuTTYPage.Surface;
354 Text:=GetPuTTYLocation+'plink.exe';
355 if not FileExists(Text) then begin
356 Text:='';
357 end;
358 Left:=ScaleX(28);
359 Top:=ScaleY(148);
360 Width:=ScaleX(316);
361 Height:=ScaleY(13);
362 end;
363 BtnPLink:=TButton.Create(PuTTYPage);
364 with BtnPLink do begin
365 Parent:=PuTTYPage.Surface;
366 Caption:='...';
367 OnClick:=@BrowseForPuTTYFolder;
368 Left:=ScaleX(348);
369 Top:=ScaleY(148);
370 Width:=ScaleX(21);
371 Height:=ScaleY(21);
372 end;
373 end;
375 function NextButtonClick(CurPageID:Integer):Boolean;
376 begin
377 if CurPageID<>PuTTYPage.ID then begin
378 Result:=True;
379 Exit;
380 end;
382 Result:=RdbOpenSSH.Checked
383 or (RdbPLink.Checked and FileExists(EdtPLink.Text));
385 if not Result then begin
386 MsgBox('Please enter a valid path to plink.exe.',mbError,MB_OK);
387 end;
388 end;
390 procedure CurStepChanged(CurStep:TSetupStep);
392 AppDir,FileName,Cmd,Msg:string;
393 BuiltIns,EnvPath,EnvHome,EnvSSH:TArrayOfString;
394 Count,i:Longint;
395 IsNTFS:Boolean;
396 RootKey:Integer;
397 begin
398 if CurStep<>ssPostInstall then begin
399 Exit;
400 end;
402 AppDir:=ExpandConstant('{app}');
405 Create the built-ins
408 // Load the built-ins from a text file.
409 FileName:=ExpandConstant('{app}\'+'{#emit APP_BUILTINS}');
410 if LoadStringsFromFile(FileName,BuiltIns) then begin
411 // Check if we are running on NTFS.
412 IsNTFS:=False;
413 if SetNTFSCompression(AppDir+'\bin\git.exe',true) then begin
414 IsNTFS:=SetNTFSCompression(AppDir+'\bin\git.exe',false);
415 end;
417 Count:=GetArrayLength(BuiltIns)-1;
419 // Delete all scripts as they might have been replaced by built-ins by now.
420 for i:=0 to Count do begin
421 FileName:=ChangeFileExt(AppDir+'\'+BuiltIns[i],'');
422 if (FileExists(FileName) and (not DeleteFile(FileName))) then begin
423 Log('Line {#emit __LINE__}: Unable to delete script "'+FileName+'", ignoring.');
424 end;
425 end;
427 // Map the built-ins to git.exe.
428 if IsNTFS then begin
429 Log('Line {#emit __LINE__}: Partition seems to be NTFS, trying to create built-in aliases as hard links.');
431 for i:=0 to Count do begin
432 FileName:=AppDir+'\'+BuiltIns[i];
434 // On non-NTFS partitions, create hard links.
435 if (FileExists(FileName) and (not DeleteFile(FileName)))
436 or (not CreateHardLink(FileName,AppDir+'\bin\git.exe',0)) then begin
437 Log('Line {#emit __LINE__}: Unable to create hard link "'+FileName+'", will try to copy files.');
438 IsNTFS:=False;
439 Break;
440 end;
441 end;
443 Log('Line {#emit __LINE__}: Successfully created built-in aliases as hard links.');
444 end;
446 // The fallback is to copy the files.
447 if not IsNTFS then begin
448 Log('Line {#emit __LINE__}: Trying to create built-in aliases as file copies.');
450 for i:=0 to Count do begin
451 FileName:=AppDir+'\'+BuiltIns[i];
453 // On non-NTFS partitions, copy simply the files (overwriting existing ones).
454 if not FileCopy(AppDir+'\bin\git.exe',FileName,false) then begin
455 Msg:='Line {#emit __LINE__}: Unable to create file copy "'+FileName+'".';
456 MsgBox(Msg,mbError,MB_OK);
457 Log(Msg);
458 // This is not a critical error, Git could basically be used without the
459 // aliases for built-ins, so we continue.
460 end;
461 end;
463 Log('Line {#emit __LINE__}: Successfully created built-in aliases as file copies.');
464 end;
465 end else begin
466 Msg:='Line {#emit __LINE__}: Unable to read file "{#emit APP_BUILTINS}".';
467 MsgBox(Msg,mbError,MB_OK);
468 Log(Msg);
469 // This is not a critical error, Git could basically be used without the
470 // aliases for built-ins, so we continue.
471 end;
474 Modify the environment
476 This must happen no later than ssPostInstall to make
477 "ChangesEnvironment=yes" not happend before the change!
480 FileName:=AppDir+'\setup.ini';
482 // Delete GIT_SSH if a previous installation modified it.
483 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
484 if (GetArrayLength(EnvSSH)=1) and
485 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',FileName))=0) then begin
486 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
487 Msg:='Line {#emit __LINE__}: Unable to reset GIT_SSH prior to install.';
488 MsgBox(Msg,mbError,MB_OK);
489 Log(Msg);
490 // This is not a critical error, the user can probably fix it manually,
491 // so we continue.
492 end;
493 end;
495 if RdbPLink.Checked then begin
496 SetArrayLength(EnvSSH,1);
497 EnvSSH[0]:=EdtPLink.Text;
498 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,EnvSSH) then begin
499 Msg:='Line {#emit __LINE__}: Unable to set the GIT_SSH environment variable.';
500 MsgBox(Msg,mbError,MB_OK);
501 Log(Msg);
502 // This is not a critical error, the user can probably fix it manually,
503 // so we continue.
504 end;
506 // Mark that we have changed GIT_SSH.
507 if not SetIniString('Environment','GIT_SSH',EnvSSH[0],FileName) then begin
508 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
509 MsgBox(Msg,mbError,MB_OK);
510 Log(Msg);
511 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
512 // so we continue.
513 end;
514 end;
516 // Get the current user's directories in PATH.
517 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
519 // First, remove the installation directory from PATH in any case.
520 for i:=0 to GetArrayLength(EnvPath)-1 do begin
521 if Pos(AppDir,EnvPath[i])=1 then begin
522 EnvPath[i]:='';
523 end;
524 end;
526 // Delete HOME if a previous installation modified it.
527 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
528 if (GetArrayLength(EnvHome)=1) and
529 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',FileName))=0) then begin
530 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
531 Msg:='Line {#emit __LINE__}: Unable to reset HOME prior to install.';
532 MsgBox(Msg,mbError,MB_OK);
533 Log(Msg);
534 // This is not a critical error, the user can probably fix it manually,
535 // so we continue.
536 end;
537 end;
539 // Modify the PATH variable as requested by the user.
540 if RdbGitCmd.Checked or RdbGitCmdTools.Checked then begin
541 i:=GetArrayLength(EnvPath);
542 SetArrayLength(EnvPath,i+1);
544 // List \cmd before \bin so \cmd has higher priority and programs in
545 // there will be called in favor of those in \bin.
546 EnvPath[i]:=ExpandConstant('{app}\cmd');
548 if RdbGitCmdTools.Checked then begin
549 SetArrayLength(EnvPath,i+2);
550 EnvPath[i+1]:=ExpandConstant('{app}\bin');
552 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
553 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
554 i:=GetArrayLength(EnvHome);
555 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
556 SetArrayLength(EnvHome,1);
557 EnvHome[0]:=ExpandConstant('{%USERPROFILE}');
558 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,EnvHome) then begin
559 Msg:='Line {#emit __LINE__}: Unable to set the HOME environment variable.';
560 MsgBox(Msg,mbError,MB_OK);
561 Log(Msg);
562 // This is not a critical error, the user can probably fix it manually,
563 // so we continue.
564 end;
566 // Mark that we have changed HOME.
567 if not SetIniString('Environment','HOME',EnvHome[0],FileName) then begin
568 Msg:='Line {#emit __LINE__}: Unable to write to file "'+FileName+'".';
569 MsgBox(Msg,mbError,MB_OK);
570 Log(Msg);
571 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
572 // so we continue.
573 end;
574 end;
575 end;
576 end;
578 // Set the current user's PATH directories.
579 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
580 Msg:='Line {#emit __LINE__}: Unable to set the PATH environment variable.';
581 MsgBox(Msg,mbError,MB_OK);
582 Log(Msg);
583 // This is not a critical error, the user can probably fix it manually,
584 // so we continue.
585 end;
588 Create the Windows Explorer shell extensions
591 if IsAdminLoggedOn then begin
592 RootKey:=HKEY_LOCAL_MACHINE;
593 end else begin
594 RootKey:=HKEY_CURRENT_USER;
595 end;
597 if IsTaskSelected('shellextension') then begin
598 Cmd:=ExpandConstant('"{syswow64}\cmd.exe"');
599 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here'))
600 or (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd+' /c "pushd "%1" && "'+AppDir+'\bin\sh.exe" --login -i"')) then begin
601 Msg:='Line {#emit __LINE__}: Unable to create "Git Bash Here" shell extension.';
602 MsgBox(Msg,mbError,MB_OK);
603 Log(Msg);
604 // This is not a critical error, the user can probably fix it manually,
605 // so we continue.
606 end;
607 end;
609 if IsTaskSelected('guiextension') then begin
610 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here'))
611 or (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command','','"'+AppDir+'\bin\wish.exe" "'+AppDir+'\bin\git-gui" "--working-dir" "%1"')) then begin
612 Msg:='Line {#emit __LINE__}: Unable to create "Git GUI Here" shell extension.';
613 MsgBox(Msg,mbError,MB_OK);
614 Log(Msg);
615 // This is not a critical error, the user can probably fix it manually,
616 // so we continue.
617 end;
618 end;
619 end;
622 Uninstaller code
625 function InitializeUninstall:Boolean;
627 FileName,NewName,Msg:string;
628 begin
629 FileName:=ExpandConstant('{app}')+'\bin\ssh-agent.exe';
630 if FileExists(FileName) then begin
631 // Create a temporary copy of the file we try to delete.
632 NewName:=FileName+'.'+IntToStr(1000+Random(9000));
633 Result:=FileCopy(FileName,NewName,True) and DeleteFile(FileName);
635 if not Result then begin
636 Msg:='Line {#emit __LINE__}: Please stop all ssh-agent processes and run uninstall again.';
637 MsgBox(Msg,mbError,MB_OK);
638 Log(Msg);
640 // Clean-up the temporary copy (ignoring any errors).
641 DeleteFile(NewName);
642 end else begin
643 // Clean-up the temporary copy (ignoring any errors).
644 RenameFile(NewName,FileName);
645 end;
646 end else begin
647 Result:=True;
648 end;
649 end;
651 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
653 AppDir,Command,Msg:string;
654 EnvPath,EnvHome,EnvSSH:TArrayOfString;
655 i:Longint;
656 RootKey:Integer;
657 begin
658 if CurUninstallStep<>usUninstall then begin
659 Exit;
660 end;
663 Modify the environment
665 This must happen no later than usUninstall to make
666 "ChangesEnvironment=yes" not happend before the change!
669 AppDir:=ExpandConstant('{app}');
670 Command:=AppDir+'\setup.ini';
672 // Reset the current user's GIT_SSH if we modified it.
673 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
674 if (GetArrayLength(EnvSSH)=1) and
675 (CompareStr(EnvSSH[0],GetIniString('Environment','GIT_SSH','',Command))=0) then begin
676 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
677 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to GIT_SSH.';
678 MsgBox(Msg,mbError,MB_OK);
679 Log(Msg);
680 // This is not a critical error, the user can probably fix it manually,
681 // so we continue.
682 end;
683 end;
685 // Get the current user's directories in PATH.
686 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
688 // Remove the installation directory from PATH in any case, even if it
689 // was not added by the installer.
690 for i:=0 to GetArrayLength(EnvPath)-1 do begin
691 if Pos(AppDir,EnvPath[i])=1 then begin
692 EnvPath[i]:='';
693 end;
694 end;
696 // Reset the current user's directories in PATH.
697 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
698 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to PATH.';
699 MsgBox(Msg,mbError,MB_OK);
700 Log(Msg);
701 // This is not a critical error, the user can probably fix it manually,
702 // so we continue.
703 end;
705 // Reset the current user's HOME if we modified it.
706 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
707 if (GetArrayLength(EnvHome)=1) and
708 (CompareStr(EnvHome[0],GetIniString('Environment','HOME','',Command))=0) then begin
709 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
710 Msg:='Line {#emit __LINE__}: Unable to revert any possible changes to HOME.';
711 MsgBox(Msg,mbError,MB_OK);
712 Log(Msg);
713 // This is not a critical error, the user can probably fix it manually,
714 // so we continue.
715 end;
716 end;
718 if (FileExists(Command) and (not DeleteFile(Command))) then begin
719 Msg:='Line {#emit __LINE__}: Unable to delete file "'+Command+'".';
720 MsgBox(Msg,mbError,MB_OK);
721 Log(Msg);
722 // This is not a critical error, the user can probably fix it manually,
723 // so we continue.
724 end;
727 Delete the Windows Explorer shell extensions
730 if IsAdminLoggedOn then begin
731 RootKey:=HKEY_LOCAL_MACHINE;
732 end else begin
733 RootKey:=HKEY_CURRENT_USER;
734 end;
736 Command:='';
737 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command);
738 if Pos(AppDir,Command)>0 then begin
739 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
740 Msg:='Line {#emit __LINE__}: Unable to remove "Git Bash Here" shell extension.';
741 MsgBox(Msg,mbError,MB_OK);
742 Log(Msg);
743 // This is not a critical error, the user can probably fix it manually,
744 // so we continue.
745 end;
746 end;
748 Command:='';
749 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command);
750 if Pos(AppDir,Command)>0 then begin
751 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
752 Msg:='Line {#emit __LINE__}: Unable to remove "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;