2 #define APP_VERSION
'%APPVERSION%'
3 #define APP_URL
'http://code.google.com/p/msysgit/'
4 #define APP_BUILTINS
'etc\fileList-builtins.txt'
8 InternalCompressLevel
=max
9 OutputBaseFilename
={#emit APP_NAME+'-'+APP_VERSION}
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}
23 InfoBeforeFile
=gpl
-2.0.rtf
24 PrivilegesRequired
=none
25 UninstallDisplayIcon
=etc\git
.ico
28 SetupIconFile
=etc\git
.ico
29 WizardSmallImageFile
=git
.bmp
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
38 Source
: "*"; DestDir
: "{app}"; Excludes
: "\*.bmp, gpl-2.0.rtf, \install.*, \tmp.*, \bin\*install*"; Flags
: recursesubdirs replacesameversion
39 Source
: ReleaseNotes
.rtf
; DestDir
: "{app}"; Flags
: isreadme replacesameversion
42 Name
: "{group}\Git GUI"; Filename
: "{app}\bin\wish.exe"; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: "%HOMEDRIVE%%HOMEPATH%"; IconFilename
: "{app}\etc\git.ico"
43 Name
: "{group}\Git Bash"; Filename
: "{syswow64}\cmd.exe"; Parameters
: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir
: "%HOMEDRIVE%%HOMEPATH%"; 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
: "%HOMEDRIVE%%HOMEPATH%"; 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
: "%HOMEDRIVE%%HOMEPATH%"; IconFilename
: "{app}\etc\git.ico"; Tasks
: desktopicon
49 BeveledLabel
={#emit APP_URL}
50 SetupAppTitle
={#emit APP_NAME} Setup
51 SetupWindowTitle
={#emit APP_NAME} Setup
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"
64 function GetShellFolder(Param
:string):string;
66 if IsAdminLoggedOn
then begin
67 Param
:='{common'+Param
+'}';
69 Param
:='{user'+Param
+'}';
71 Result
:=ExpandConstant(Param
);
74 function CreateHardLink(lpFileName
,lpExistingFileName
:string;lpSecurityAttributes
:Integer):Boolean;
75 external 'CreateHardLinkA@Kernel32.dll';
77 function GetEnvStrings(VarName
:string;AllUsers
:Boolean):TArrayOfString
;
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
);
90 // We ignore errors here
. The resulting
array of strings will be empty
.
91 RegQueryStringValue(HKEY_CURRENT_USER
,'Environment',VarName
,Path
);
94 // Make sure we have at least one semicolon
.
97 // Split the directories
in PATH into an
array of strings
.
99 SetArrayLength(Result
,0);
103 SetArrayLength(Result
,i
+1);
105 Result
[i
]:=Copy(Path
,1,p
-1);
108 Path
:=Copy(Path
,p
+1,Length(Path
));
113 function SetEnvStrings(VarName
:string;AllUsers
,DeleteIfEmpty
:Boolean;DirStrings
:TArrayOfString
):Boolean;
118 // Merge all non
-empty directory strings into a PATH variable
.
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
];
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
);
137 Result
:=RegWriteStringValue(HKEY_LOCAL_MACHINE
,KeyName
,VarName
,Path
);
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
);
145 Result
:=RegWriteStringValue(HKEY_CURRENT_USER
,KeyName
,VarName
,Path
);
151 TortoiseSVNInstallKey
='SOFTWARE\TortoiseSVN';
152 TortoiseCVSUninstallKey
='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\TortoiseCVS_is1';
153 PuTTYUninstallKey
='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PuTTY_is1';
154 PuTTYPrivateKeyAssoc
='PuTTYPrivateKey\shell\open\command';
156 function GetPuTTYLocation
:string;
158 // Prefer TortoisePlink over vanilla Plink
for its GUI dialog
to accept host keys
.
159 if (IsWin64
and RegQueryStringValue(HKEY_LOCAL_MACHINE_64
,TortoiseSVNInstallKey
,'Directory',Result
))
160 or RegQueryStringValue(HKEY_LOCAL_MACHINE_32
,TortoiseSVNInstallKey
,'Directory',Result
) then begin
161 // C
:\
Program Files\TortoiseSVN\
162 Result
:=Result
+'bin\';
163 // C:\Program Files\TortoiseSVN\bin\
165 if not (IsWin64 and RegQueryStringValue(HKEY_LOCAL_MACHINE_64,TortoiseCVSUninstallKey,'InstallLocation
',Result)) then begin
166 RegQueryStringValue(HKEY_LOCAL_MACHINE_32,TortoiseCVSUninstallKey,'InstallLocation
',Result);
168 // C:\Program Files\TortoiseCVS\
171 if DirExists(Result) then begin
172 Result:=Result+'TortoisePlink
.exe
'
176 if not RegQueryStringValue(HKEY_LOCAL_MACHINE,PuTTYUninstallKey,'InstallLocation
',Result) then begin
177 if RegQueryStringValue(HKEY_CLASSES_ROOT,PuTTYPrivateKeyAssoc,'',Result) then begin
178 // "C:\Program Files\PuTTY\pageant.exe" "%1"
179 Result:=RemoveQuotes(Result);
180 // C:\Program Files\PuTTY\pageant.exe" "%1
181 Result:=ExtractFilePath(Result);
184 // C:\Program Files\PuTTY\
186 if not DirExists(Result) then begin
188 Result:='C
:\
Program Files\PuTTY
\';
191 Result
:=Result
+'plink.exe'
207 GC_CRLFCommitAsIs
= 3;
210 // Wizard page
and variables
for the Path options
.
211 PathPage
:TWizardPage
;
212 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
214 // Wizard page
and variables
for the SSH options
.
215 PuTTYPage
:TWizardPage
;
216 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
219 // Wizard page
and variables
for the CR
/LF options
.
220 CRLFPage
:TWizardPage
;
221 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
223 procedure BrowseForPuTTYFolder(Sender
:TObject
);
227 Path
:=ExtractFilePath(EdtPlink
.Text);
228 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
229 if FileExists(Path
+'\TortoisePlink.exe') then begin
230 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
231 RdbSSH
[GS_Plink
].Checked
:=True;
232 end else if FileExists(Path
+'\plink.exe') then begin
233 EdtPlink
.Text:=Path
+'\plink.exe';
234 RdbSSH
[GS_Plink
].Checked
:=True;
236 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
244 procedure InitializeWizard
;
246 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
247 LblOpenSSH
,LblPlink
:TLabel
;
248 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
252 // Create a custom page
for modifying the environment
.
253 PathPage
:=CreateCustomPage(
255 'Adjusting your PATH environment',
256 'How would you like to use Git from the command line?'
260 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
261 with RdbPath
[GP_BashOnly
] do begin
262 Parent
:=PathPage
.Surface
;
263 Caption
:='Use Git Bash only';
268 Font
.Style
:=[fsBold
];
272 LblGitBash
:=TLabel
.Create(PathPage
);
273 with LblGitBash
do begin
274 Parent
:=PathPage
.Surface
;
276 'This is the most conservative choice if you are concerned about the stability' + #
13 +
277 'of your system. Your PATH will not be modified.';
285 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
286 with RdbPath
[GP_Cmd
] do begin
287 Parent
:=PathPage
.Surface
;
288 Caption
:='Run Git from the Windows Command Prompt';
293 Font
.Style
:=[fsBold
];
296 LblGitCmd
:=TLabel
.Create(PathPage
);
297 with LblGitCmd
do begin
298 Parent
:=PathPage
.Surface
;
300 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
301 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
302 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
310 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
311 with RdbPath
[GP_CmdTools
] do begin
312 Parent
:=PathPage
.Surface
;
313 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
318 Font
.Style
:=[fsBold
];
321 LblGitCmdTools
:=TLabel
.Create(PathPage
);
322 with LblGitCmdTools
do begin
323 Parent
:=PathPage
.Surface
;
324 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
330 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
331 with LblGitCmdToolsWarn
do begin
332 Parent
:=PathPage
.Surface
;
334 'Warning: This will override Windows tools like find.exe and' + #
13 +
335 'sort.exe. Select this option only if you understand the implications.';
341 Font
.Style
:=[fsBold
];
344 // Restore the setting chosen during a previous install
.
345 Data
:=GetPreviousData('Path Option','BashOnly');
346 if Data
='BashOnly' then begin
347 RdbPath
[GP_BashOnly
].Checked
:=True;
348 end else if Data
='Cmd' then begin
349 RdbPath
[GP_Cmd
].Checked
:=True;
350 end else if Data
='CmdTools' then begin
351 RdbPath
[GP_CmdTools
].Checked
:=True;
354 // Create a custom page
for using (Tortoise
)Plink instead
of OpenSSH
.
355 PuTTYPage
:=CreateCustomPage(
357 'Choosing the SSH executable',
358 'Which Secure Shell client program would you like Git to use?'
362 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
363 with RdbSSH
[GS_OpenSSH
] do begin
364 Parent
:=PuTTYPage
.Surface
;
365 Caption
:='Use OpenSSH';
370 Font
.Style
:=[fsBold
];
374 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
375 with LblOpenSSH
do begin
376 Parent
:=PuTTYPage
.Surface
;
378 'This uses ssh.exe that comes with Git. The GIT_SSH environment' + #
13 +
379 'variable will not be modified.';
387 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
388 with RdbSSH
[GS_Plink
] do begin
389 Parent
:=PuTTYPage
.Surface
;
390 Caption
:='Use (Tortoise)Plink';
395 Font
.Style
:=[fsBold
];
398 LblPlink
:=TLabel
.Create(PuTTYPage
);
399 with LblPlink
do begin
400 Parent
:=PuTTYPage
.Surface
;
402 'This uses (Tortoise)Plink.exe from the TortoiseSVN/CVS or PuTTY' + #
13 +
403 'applications which need to be provided by the user. The GIT_SSH' + #
13 +
404 'environment variable will be set to the executable specified below.';
410 EdtPlink
:=TEdit
.Create(PuTTYPage
);
411 with EdtPlink
do begin
412 Parent
:=PuTTYPage
.Surface
;
413 Text:=GetPuTTYLocation
;
414 if not FileExists(Text) then begin
422 BtnPlink
:=TButton
.Create(PuTTYPage
);
423 with BtnPlink
do begin
424 Parent
:=PuTTYPage
.Surface
;
426 OnClick
:=@BrowseForPuTTYFolder
;
433 // Restore the setting chosen during a previous install
.
434 Data
:=GetPreviousData('SSH Option','OpenSSH');
435 if Data
='OpenSSH' then begin
436 RdbSSH
[GS_OpenSSH
].Checked
:=True;
437 end else if Data
='Plink' then begin
438 RdbSSH
[GS_Plink
].Checked
:=True;
441 // Create a custom page
for the autoCRLF setting
.
442 CRLFPage
:=CreateCustomPage(
444 'Choosing CR/LF behavior',
445 'Which CR/LF behavior would you like Git to have?'
449 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
450 with RdbCRLF
[GC_LFOnly
] do begin
451 Parent
:=CRLFPage
.Surface
;
452 Caption
:='Use Unix style line endings';
457 Font
.Style
:=[fsBold
];
461 LblLFOnly
:=TLabel
.Create(CRLFPage
);
462 with LblLFOnly
do begin
463 Parent
:=CRLFPage
.Surface
;
465 'Choose this if a single Line Feed character ends your lines. Most Windows' + #
13 +
466 'programs can cope with these line endings. However, some editors, like' + #
13 +
467 'Notepad, will show everything in one line with this mode.';
475 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
476 with RdbCRLF
[GC_CRLFAlways
] do begin
477 Parent
:=CRLFPage
.Surface
;
478 Caption
:='Use Windows style line endings';
483 Font
.Style
:=[fsBold
];
487 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
488 with LblCRLFAlways
do begin
489 Parent
:=CRLFPage
.Surface
;
491 'Choose this if your source code uses a Carriage Return and a Line Feed' + #
13 +
492 'character to end lines. This is the DOS convention; your checked-out files' + #
13 +
493 'might not be handled gracefully by MSYS / Cygwin command line utilities.';
501 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
502 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
503 Parent
:=CRLFPage
.Surface
;
504 Caption
:='Commit line endings as they are';
509 Font
.Style
:=[fsBold
];
513 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
514 with LblCRLFCommitAsIs
do begin
515 Parent
:=CRLFPage
.Surface
;
517 'Choose this if you know what you are doing and want to track the files with' + #
13 +
518 'the line endings exactly as they appear in the files. This option might' + #
13 +
519 'cause your projects to be hard to use on other platforms.';
526 // Restore the setting chosen during a previous install
.
527 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
528 if Data
='LFOnly' then begin
529 RdbCRLF
[GC_LFOnly
].Checked
:=True;
530 end else if Data
='CRLFAlways' then begin
531 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
532 end else if Data
='CRLFCommitAsIs' then begin
533 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
537 function NextButtonClick(CurPageID
:Integer):Boolean;
539 if CurPageID
<>PuTTYPage
.ID
then begin
544 Result
:=RdbSSH
[GS_OpenSSH
].Checked
545 or (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
547 if not Result
then begin
548 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
552 procedure CurStepChanged(CurStep
:TSetupStep
);
554 AppDir
,FileName
,Cmd
,Msg
:string;
555 BuiltIns
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
561 if CurStep
<>ssPostInstall
then begin
565 AppDir
:=ExpandConstant('{app}');
571 // Load the built
-ins from a
text file.
572 FileName
:=ExpandConstant('{app}\'+'{#emit APP_BUILTINS}');
573 if LoadStringsFromFile(FileName,BuiltIns) then begin
574 // Check if we are running on NTFS.
576 if SetNTFSCompression(AppDir+'\bin\git
.exe
',true) then begin
577 IsNTFS:=SetNTFSCompression(AppDir+'\bin\git
.exe
',false);
580 Count:=GetArrayLength(BuiltIns)-1;
582 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
583 for i:=0 to Count do begin
584 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
585 if (FileExists(FileName
) and (not DeleteFile(FileName
))) then begin
586 Log('Line {#emit __LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
590 // Map the built
-ins
to git
.exe
.
592 Log('Line {#emit __LINE__}: Partition seems to be NTFS, trying to create built-in aliases as hard links.');
594 for i
:=0 to Count
do begin
595 FileName
:=AppDir
+'\'+BuiltIns[i];
597 // On non-NTFS partitions, create hard links.
598 if (FileExists(FileName) and (not DeleteFile(FileName)))
599 or (not CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0)) then begin
600 Log('Line
{#emit __LINE__}: Unable
to create hard link
"'+FileName+'", will
try to copy
files.');
606 Log('Line
{#emit __LINE__}: Successfully created built
-in aliases
as hard links
.');
609 // The fallback is to copy the files.
610 if not IsNTFS then begin
611 Log('Line
{#emit __LINE__}: Trying
to create built
-in aliases
as file copies
.');
613 for i:=0 to Count do begin
614 FileName:=AppDir+'\'+BuiltIns
[i
];
616 // On non
-NTFS partitions
, copy simply the
files (overwriting existing ones
).
617 if not FileCopy(AppDir
+'\bin\git.exe',FileName
,false) then begin
618 Msg
:='Line {#emit __LINE__}: Unable to create file copy "'+FileName
+'".';
619 MsgBox(Msg
,mbError
,MB_OK
);
621 // This
is not a critical error
, Git could basically be used without the
622 // aliases
for built
-ins
, so we continue
.
626 Log('Line {#emit __LINE__}: Successfully created built-in aliases as file copies.');
629 // Delete any duplicate
files in case we are updating from a non
-libexec
to a libexec directory layout
.
630 if FindFirst(AppDir
+'\libexec\git-core\*',FindRec
) then begin
632 if (FindRec
.Attributes
and FILE_ATTRIBUTE_DIRECTORY
)=0 then begin
633 FileName
:=AppDir
+'\bin\'+FindRec.name;
634 if ((not Pos(FindRec.name,'git
.exe
')=1) and FileExists(FileName) and (not DeleteFile(FileName))) then begin
635 Log('Line
{#emit __LINE__}: Unable
to delete dupe
"'+FileName+'", ignoring
.');
638 until not FindNext(FindRec);
642 Msg:='Line
{#emit __LINE__}: Unable
to read file "{#emit APP_BUILTINS}".';
643 MsgBox(Msg,mbError,MB_OK);
645 // This is not a critical error, Git could basically be used without the
646 // aliases for built-ins, so we continue.
653 if RdbCRLF[GC_LFOnly].checked then begin
654 Cmd:='core
.autoCRLF input
';
655 end else if RdbCRLF[GC_CRLFAlways].checked then begin
656 Cmd:='core
.autoCRLF
true';
658 Cmd:='core
.autoCRLF
false';
660 if not Exec(AppDir + '\bin\git
.exe
', 'config
-f gitconfig
' + Cmd,
661 AppDir + '\etc
', SW_HIDE, ewWaitUntilTerminated, i) then begin
662 Msg:='Could
not set CR
/LF behavior
: ' + Cmd;
663 MsgBox(Msg,mbError,MB_OK);
668 Modify the environment
670 This must happen no later than ssPostInstall to make
671 "ChangesEnvironment=yes" not happend before the change!
674 FileName:=AppDir+'\setup
.ini
';
676 // Delete GIT_SSH if a previous installation modified it.
677 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
678 if (GetArrayLength(EnvSSH)=1) and
679 (CompareStr(EnvSSH[0],GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
680 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
681 Msg:='Line
{#emit __LINE__}: Unable
to reset GIT_SSH prior
to install
.';
682 MsgBox(Msg,mbError,MB_OK);
684 // This is not a critical error, the user can probably fix it manually,
689 if RdbSSH[GS_Plink].Checked then begin
690 SetArrayLength(EnvSSH,1);
691 EnvSSH[0]:=EdtPlink.Text;
692 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,EnvSSH) then begin
693 Msg:='Line
{#emit __LINE__}: Unable
to set the GIT_SSH environment variable
.';
694 MsgBox(Msg,mbError,MB_OK);
696 // This is not a critical error, the user can probably fix it manually,
700 // Mark that we have changed GIT_SSH.
701 if not SetIniString('Environment
','GIT_SSH
',EnvSSH[0],FileName) then begin
702 Msg:='Line
{#emit __LINE__}: Unable
to write
to file "'+FileName+'".';
703 MsgBox(Msg,mbError,MB_OK);
705 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
710 // Get the current user's directories
in PATH
.
711 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
713 // First
, remove the installation directory from PATH
in any
case.
714 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
715 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
720 // Delete HOME
if a previous installation modified it
.
721 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
722 if (GetArrayLength(EnvHome
)=1) and
723 (CompareStr(EnvHome
[0],GetIniString('Environment','HOME','',FileName
))=0) then begin
724 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
725 Msg
:='Line {#emit __LINE__}: Unable to reset HOME prior to install.';
726 MsgBox(Msg
,mbError
,MB_OK
);
728 // This
is not a critical error
, the user can probably fix it manually
,
733 // Modify the PATH variable
as requested by the user
.
734 if RdbPath
[GP_Cmd
].Checked
or RdbPath
[GP_CmdTools
].Checked
then begin
735 i
:=GetArrayLength(EnvPath
);
736 SetArrayLength(EnvPath
,i
+1);
738 // List \cmd before
\bin so \cmd has higher priority
and programs
in
739 // there will be called
in favor
of those
in \bin
.
740 EnvPath
[i
]:=ExpandConstant('{app}\cmd');
742 if RdbPath
[GP_CmdTools
].Checked
then begin
743 SetArrayLength(EnvPath
,i
+2);
744 EnvPath
[i
+1]:=ExpandConstant('{app}\bin');
746 // Set HOME
for the Windows Command Prompt
, but only
if it has
not been
set manually before
.
747 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
748 i
:=GetArrayLength(EnvHome
);
749 if (i
=0) or ((i
=1) and (Length(EnvHome
[0])=0)) then begin
750 SetArrayLength(EnvHome
,1);
751 EnvHome
[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
752 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,EnvHome
) then begin
753 Msg
:='Line {#emit __LINE__}: Unable to set the HOME environment variable.';
754 MsgBox(Msg
,mbError
,MB_OK
);
756 // This
is not a critical error
, the user can probably fix it manually
,
760 // Mark that we have changed HOME
.
761 if not SetIniString('Environment','HOME',EnvHome
[0],FileName
) then begin
762 Msg
:='Line {#emit __LINE__}: Unable to write to file "'+FileName
+'".';
763 MsgBox(Msg
,mbError
,MB_OK
);
765 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
772 // Set the current user
's PATH directories.
773 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
774 Msg:='Line
{#emit __LINE__}: Unable
to set the PATH environment variable
.';
775 MsgBox(Msg,mbError,MB_OK);
777 // This is not a critical error, the user can probably fix it manually,
782 Create the Windows Explorer shell extensions
785 if IsAdminLoggedOn then begin
786 RootKey:=HKEY_LOCAL_MACHINE;
788 RootKey:=HKEY_CURRENT_USER;
791 if IsTaskSelected('shellextension
') then begin
792 Cmd:=ExpandConstant('"{syswow64}\cmd.exe"');
793 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell
','','Git Ba
&sh Here
'))
794 or (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command
','',Cmd+' /c
"pushd "%1" && "'+AppDir+'\bin\sh
.exe
" --login -i"')) then begin
795 Msg:='Line
{#emit __LINE__}: Unable
to create
"Git Bash Here" shell extension
.';
796 MsgBox(Msg,mbError,MB_OK);
798 // This is not a critical error, the user can probably fix it manually,
803 if IsTaskSelected('guiextension
') then begin
804 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui
','','Git
&GUI Here
'))
805 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
806 Msg:='Line
{#emit __LINE__}: Unable
to create
"Git GUI Here" shell extension
.';
807 MsgBox(Msg,mbError,MB_OK);
809 // This is not a critical error, the user can probably fix it manually,
815 procedure RegisterPreviousData(PreviousDataKey:Integer);
821 if RdbPath[GP_BashOnly].Checked then begin
823 end else if RdbPath[GP_Cmd].Checked then begin
825 end else if RdbPath[GP_CmdTools].Checked then begin
828 SetPreviousData(PreviousDataKey,'Path Option
',Data);
832 if RdbSSH[GS_OpenSSH].Checked then begin
834 end else if RdbSSH[GS_Plink].Checked then begin
837 SetPreviousData(PreviousDataKey,'SSH Option
',Data);
839 // Git CR/LF options.
841 if RdbCRLF[GC_LFOnly].Checked then begin
843 end else if RdbCRLF[GC_CRLFAlways].Checked then begin
845 end else if RdbCRLF[GC_CRLFCommitAsIs].Checked then begin
846 Data:='CRLFCommitAsIs
';
848 SetPreviousData(PreviousDataKey,'CRLF Option
',Data);
855 function InitializeUninstall:Boolean;
857 FileName,NewName,Msg:string;
859 FileName:=ExpandConstant('{app}')+'\bin\ssh
-agent
.exe
';
860 if FileExists(FileName) then begin
861 // Create a temporary copy of the file we try to delete.
862 NewName:=FileName+'.'+IntToStr(1000+Random(9000));
863 Result:=FileCopy(FileName,NewName,True) and DeleteFile(FileName);
865 if not Result then begin
866 Msg:='Line
{#emit __LINE__}: Please stop all ssh
-agent processes
and run uninstall again
.';
867 MsgBox(Msg,mbError,MB_OK);
870 // Clean-up the temporary copy (ignoring any errors).
873 // Clean-up the temporary copy (ignoring any errors).
874 RenameFile(NewName,FileName);
881 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
883 AppDir,Command,Msg:string;
884 EnvPath,EnvHome,EnvSSH:TArrayOfString;
888 if CurUninstallStep<>usUninstall then begin
893 Modify the environment
895 This must happen no later than usUninstall to make
896 "ChangesEnvironment=yes" not happend before the change!
899 AppDir:=ExpandConstant('{app}');
900 Command:=AppDir+'\setup
.ini
';
902 // Reset the current user's GIT_SSH
if we modified it
.
903 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
904 if (GetArrayLength(EnvSSH
)=1) and
905 (CompareStr(EnvSSH
[0],GetIniString('Environment','GIT_SSH','',Command
))=0) then begin
906 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
907 Msg
:='Line {#emit __LINE__}: Unable to revert any possible changes to GIT_SSH.';
908 MsgBox(Msg
,mbError
,MB_OK
);
910 // This
is not a critical error
, the user can probably fix it manually
,
915 // Get the current user
's directories in PATH.
916 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
918 // Remove the installation directory from PATH in any case, even if it
919 // was not added by the installer.
920 for i:=0 to GetArrayLength(EnvPath)-1 do begin
921 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
926 // Reset the current user's directories
in PATH
.
927 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
928 Msg
:='Line {#emit __LINE__}: Unable to revert any possible changes to PATH.';
929 MsgBox(Msg
,mbError
,MB_OK
);
931 // This
is not a critical error
, the user can probably fix it manually
,
935 // Reset the current user
's HOME if we modified it.
936 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
937 if (GetArrayLength(EnvHome)=1) and
938 (CompareStr(EnvHome[0],GetIniString('Environment
','HOME
','',Command))=0) then begin
939 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
940 Msg:='Line
{#emit __LINE__}: Unable
to revert any possible changes
to HOME
.';
941 MsgBox(Msg,mbError,MB_OK);
943 // This is not a critical error, the user can probably fix it manually,
948 if (FileExists(Command) and (not DeleteFile(Command))) then begin
949 Msg:='Line
{#emit __LINE__}: Unable
to delete
file "'+Command+'".';
950 MsgBox(Msg,mbError,MB_OK);
952 // This is not a critical error, the user can probably fix it manually,
957 Delete the Windows Explorer shell extensions
960 if IsAdminLoggedOn then begin
961 RootKey:=HKEY_LOCAL_MACHINE;
963 RootKey:=HKEY_CURRENT_USER;
967 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command
','',Command);
968 if Pos(AppDir,Command)>0 then begin
969 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell
') then begin
970 Msg:='Line
{#emit __LINE__}: Unable
to remove
"Git Bash Here" shell extension
.';
971 MsgBox(Msg,mbError,MB_OK);
973 // This is not a critical error, the user can probably fix it manually,
979 RegQueryStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui\command
','',Command);
980 if Pos(AppDir,Command)>0 then begin
981 if not RegDeleteKeyIncludingSubkeys(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui
') then begin
982 Msg:='Line
{#emit __LINE__}: Unable
to remove
"Git GUI Here" shell extension
.';
983 MsgBox(Msg,mbError,MB_OK);
985 // This is not a critical error, the user can probably fix it manually,