2 #define APP_VERSION
'%APPVERSION%'
3 #define APP_URL
'http://msysgit.googlecode.com/'
4 #define APP_BUILTINS
'etc\fileList-builtins.txt'
5 #define APP_BINDIMAGE
'etc\fileList-bindimage.txt'
7 #define COMP_CONSOLE_FONT
'Use a TrueType font in all console windows (not only for Git Bash)'
9 #define DROP_HANDLER_GUID
'{{86C86720-42A0-1069-A2E8-08002B30309D}}'
13 Compression
=lzma2
/ultra
14 LZMAUseSeparateProcess
=yes
15 OutputBaseFilename
={#APP_NAME+'-'+APP_VERSION}
16 OutputDir
={#GetEnv('USERPROFILE')}
19 ; Uncomment the line below to be able to compile the script from within the IDE.
20 ;SourceDir={#GetEnv('TEMP')}\WinGit
25 AppPublisher
=The Git Development Community
26 AppPublisherURL
={#APP_URL}
27 AppVersion
={#APP_VERSION}
28 ChangesEnvironment
=yes
29 DefaultDirName
={pf}\
{#APP_NAME}
31 DefaultGroupName
={#APP_NAME}
32 DisableProgramGroupPage
=auto
34 InfoBeforeFile
=gpl
-2.0.rtf
35 PrivilegesRequired
=none
36 UninstallDisplayIcon
={app}\etc\git
.ico
37 #
if Pos('-',APP_VERSION
)>0
38 VersionInfoVersion
={#Copy(APP_VERSION,1,Pos('-',APP_VERSION)-1)}
40 VersionInfoVersion
={#APP_VERSION}
44 SetupIconFile
=etc\git
.ico
45 WizardImageBackColor
=clWhite
47 WizardImageFile
=git
.bmp
48 WizardSmallImageFile
=gitsmall
.bmp
51 ; Define a dummy type to avoid getting the default ones.
52 Name
: custom
; Description
: Custom installation
; Flags
: iscustom
55 Name
: icons
; Description
: Additional icons
; Types
: custom
56 Name
: icons\quicklaunch
; Description
: In the Quick Launch
; Types
: custom
57 Name
: icons\desktop
; Description
: On the Desktop
; Types
: custom
58 Name
: ext
; Description
: Windows Explorer integration
; Types
: custom
59 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: custom
60 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: custom
61 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: custom
62 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: custom
63 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: custom
64 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: custom
65 Name
: consolefont
; Description
: {#COMP_CONSOLE_FONT}; Types
: custom
68 ; Install files that might be in use during setup under a different name.
69 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
70 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
72 Source
: *; DestDir
: {app}; Excludes
: \
*.bmp
, gpl
-2.0.rtf
, \
*.iss
, \tmp
.*, \bin\
*install
*, \git
-cheetah\git_shell_ext
.dll
, \git
-cheetah\git_shell_ext64
.dll
; Flags
: recursesubdirs replacesameversion sortfilesbyextension
73 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion
76 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
77 Name
: {group}\Git Bash
; Filename
: {syswow64}\cmd
.exe
; Parameters
: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
80 BeveledLabel
={#APP_URL}
81 SetupAppTitle
={#APP_NAME} Setup
82 SetupWindowTitle
={#APP_NAME} Setup
85 ; There is no "Console" key in HKLM.
86 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
87 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
88 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
89 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
91 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
92 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
93 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
94 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
96 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
97 ; is a member of the local Administrators group or not (see the "Check" argument).
99 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
100 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
101 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
102 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
103 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
104 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
105 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
107 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
108 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
109 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
110 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
111 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
112 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
114 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
115 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
116 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
117 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
118 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
119 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
121 ; Associate .sh extension with sh.exe so those files are double-clickable,
122 ; startable from cmd.exe, and when files are dropped on them they are passed
123 ; as arguments to the script.
125 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
126 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
127 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
128 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: "{syswow64}\cmd.exe /C """"{app}\bin\sh.exe"" ""--login"" ""%1"" %*"""; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
129 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\DefaultIcon
; ValueType
: string; ValueData
: "%SystemRoot%\System32\shell32.dll,-153"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
130 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
132 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
133 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
134 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
135 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: "{syswow64}\cmd.exe /C """"{app}\bin\sh.exe"" ""--login"" ""%1"" %*"""; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
136 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\DefaultIcon
; ValueType
: string; ValueData
: "%SystemRoot%\System32\shell32.dll,-153"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
137 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
140 ; Delete the built-ins.
141 Type: files; Name
: {app}\bin\git
-*.exe
142 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
143 Type: files; Name
: {app}\libexec\git
-core\git
.exe
145 ; Delete any (temporary) git-cheetah files.
146 Type: files; Name
: {app}\git
-cheetah\
*.*
148 ; Delete any manually created shortcuts.
149 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
150 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
151 Type: files; Name
: {app}\Git Bash
.lnk
153 ; Delete a home directory inside the msysGit directory.
154 Type: dirifempty; Name
: {app}\home\
{username}
155 Type: dirifempty; Name
: {app}\home
158 #include
"helpers.inc.iss"
159 #include
"environment.inc.iss"
160 #include
"putty.inc.iss"
161 #include
"modules.inc.iss"
163 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
165 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
167 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
170 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
171 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
183 // Git line ending conversion options
.
186 GC_CRLFCommitAsIs
= 3;
188 // BindImageEx API constants
.
189 BIND_NO_BOUND_IMPORTS
= $00000001;
190 BIND_NO_UPDATE
= $00000002;
191 BIND_ALL_IMAGES
= $00000004;
192 BIND_CACHE_IMPORT_DLLS
= $00000008;
195 // Wizard page
and variables
for the Path options
.
196 PathPage
:TWizardPage
;
197 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
199 // Wizard page
and variables
for the SSH options
.
200 PuTTYPage
:TWizardPage
;
201 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
204 // Wizard page
and variables
for the line ending conversion options
.
205 CRLFPage
:TWizardPage
;
206 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
208 // Wizard page
and variables
for the processes page
.
210 Processes
:ProcessList
;
211 ProcessesPage
:TWizardPage
;
212 ProcessesListBox
:TListBox
;
213 ProcessesRefresh
,ContinueButton
:TButton
;
215 procedure BrowseForPuTTYFolder(Sender
:TObject
);
219 Path
:=ExtractFilePath(EdtPlink
.Text);
220 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
221 if FileExists(Path
+'\TortoisePlink.exe') then begin
222 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
223 RdbSSH
[GS_Plink
].Checked
:=True;
224 end else if FileExists(Path
+'\plink.exe') then begin
225 EdtPlink
.Text:=Path
+'\plink.exe';
226 RdbSSH
[GS_Plink
].Checked
:=True;
228 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
232 procedure DeleteContextMenuEntries
;
234 AppDir
,Command
,Msg
:String;
237 AppDir
:=ExpandConstant('{app}');
239 if IsAdminLoggedOn
then begin
240 RootKey
:=HKEY_LOCAL_MACHINE
;
242 RootKey
:=HKEY_CURRENT_USER
;
246 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command
);
247 if Pos(AppDir
,Command
)>0 then begin
248 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
249 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash Here" shell extension.';
250 MsgBox(Msg
,mbError
,MB_OK
);
252 // This
is not a critical error
, the user can probably fix it manually
,
258 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command
);
259 if Pos(AppDir
,Command
)>0 then begin
260 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
261 Msg
:='Line {#__LINE__}: Unable to remove "Git GUI Here" shell extension.';
262 MsgBox(Msg
,mbError
,MB_OK
);
264 // This
is not a critical error
, the user can probably fix it manually
,
270 procedure RefreshProcessList(Sender
:TObject
);
272 Version
:TWindowsVersion
;
273 Modules
:TArrayOfString
;
274 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
277 ManualClosingRequired
:Boolean;
279 GetWindowsVersionEx(Version
);
281 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
282 if Version
.Major
>=6 then begin
283 SetArrayLength(Modules
,5);
284 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
285 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
286 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
287 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
288 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
289 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
291 SetArrayLength(Modules
,3);
292 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
293 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
294 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
295 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
297 SetArrayLength(Modules
,2);
298 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
299 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
300 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
302 // Misuse the
"Restartable" flag
to indicate which processes are required
303 // to be closed before setup can continue
, and which just should be closed
304 // in order
to make changes take effect immediately
.
305 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
306 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
307 Processes
[i
]:=ProcsCloseRequired
[i
];
308 Processes
[i
].Restartable
:=False;
310 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
311 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
312 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
316 ManualClosingRequired
:=False;
318 ProcessesListBox
.Items
.Clear
;
319 if (Sender
=NIL) or (SessionHandle
>0) then begin
320 for i
:=0 to GetArrayLength(Processes
)-1 do begin
321 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
322 if Processes
[i
].Restartable
then begin
323 Caption
:=Caption
+', closing is optional';
325 Caption
:=Caption
+', closing is required';
326 ManualClosingRequired
:=True;
328 Caption
:=Caption
+')';
329 ProcessesListBox
.Items
.Append(Caption
);
333 if ContinueButton
<>NIL then begin
334 ContinueButton
.Enabled
:=not ManualClosingRequired
;
342 procedure InitializeWizard
;
345 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
346 LblOpenSSH
,LblPlink
:TLabel
;
347 PuTTYSessions
:TArrayOfString
;
348 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
353 PrevPageID
:=wpSelectProgramGroup
;
356 * Create a custom page for modifying the environment.
359 PathPage
:=CreateCustomPage(
361 'Adjusting your PATH environment',
362 'How would you like to use Git from the command line?'
364 PrevPageID
:=PathPage
.ID
;
367 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
368 with RdbPath
[GP_BashOnly
] do begin
369 Parent
:=PathPage
.Surface
;
370 Caption
:='Use Git Bash only';
375 Font
.Style
:=[fsBold
];
379 LblGitBash
:=TLabel
.Create(PathPage
);
380 with LblGitBash
do begin
381 Parent
:=PathPage
.Surface
;
383 'This is the most conservative choice if you are concerned about the stability' + #
13 +
384 'of your system. Your PATH will not be modified.';
392 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
393 with RdbPath
[GP_Cmd
] do begin
394 Parent
:=PathPage
.Surface
;
395 Caption
:='Run Git from the Windows Command Prompt';
400 Font
.Style
:=[fsBold
];
403 LblGitCmd
:=TLabel
.Create(PathPage
);
404 with LblGitCmd
do begin
405 Parent
:=PathPage
.Surface
;
407 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
408 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
409 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
417 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
418 with RdbPath
[GP_CmdTools
] do begin
419 Parent
:=PathPage
.Surface
;
420 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
425 Font
.Style
:=[fsBold
];
428 LblGitCmdTools
:=TLabel
.Create(PathPage
);
429 with LblGitCmdTools
do begin
430 Parent
:=PathPage
.Surface
;
431 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
437 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
438 with LblGitCmdToolsWarn
do begin
439 Parent
:=PathPage
.Surface
;
441 'Warning: This will override Windows tools like find.exe and' + #
13 +
442 'sort.exe. Select this option only if you understand the implications.';
448 Font
.Style
:=[fsBold
];
451 // Restore the setting chosen during a previous install
.
452 Data
:=GetPreviousData('Path Option','BashOnly');
453 if Data
='BashOnly' then begin
454 RdbPath
[GP_BashOnly
].Checked
:=True;
455 end else if Data
='Cmd' then begin
456 RdbPath
[GP_Cmd
].Checked
:=True;
457 end else if Data
='CmdTools' then begin
458 RdbPath
[GP_CmdTools
].Checked
:=True;
462 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
463 * if at least one PuTTY session is found in the Registry.
466 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
467 PuTTYPage
:=CreateCustomPage(
469 'Choosing the SSH executable',
470 'Which Secure Shell client program would you like Git to use?'
472 PrevPageID
:=PuTTYPage
.ID
;
475 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
476 with RdbSSH
[GS_OpenSSH
] do begin
477 Parent
:=PuTTYPage
.Surface
;
478 Caption
:='Use OpenSSH';
483 Font
.Style
:=[fsBold
];
487 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
488 with LblOpenSSH
do begin
489 Parent
:=PuTTYPage
.Surface
;
491 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
492 'environment variables will not be modified.';
500 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
501 with RdbSSH
[GS_Plink
] do begin
502 Parent
:=PuTTYPage
.Surface
;
503 Caption
:='Use (Tortoise)Plink';
508 Font
.Style
:=[fsBold
];
511 LblPlink
:=TLabel
.Create(PuTTYPage
);
512 with LblPlink
do begin
513 Parent
:=PuTTYPage
.Surface
;
515 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
516 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
517 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
518 'variables will be adjusted to point to the following executable:';
524 EdtPlink
:=TEdit
.Create(PuTTYPage
);
525 with EdtPlink
do begin
526 Parent
:=PuTTYPage
.Surface
;
527 Text:=GetPuTTYLocation
;
528 if not FileExists(Text) then begin
536 BtnPlink
:=TButton
.Create(PuTTYPage
);
537 with BtnPlink
do begin
538 Parent
:=PuTTYPage
.Surface
;
540 OnClick
:=@BrowseForPuTTYFolder
;
547 // Restore the setting chosen during a previous install
.
548 Data
:=GetPreviousData('SSH Option','OpenSSH');
549 if Data
='OpenSSH' then begin
550 RdbSSH
[GS_OpenSSH
].Checked
:=True;
551 end else if Data
='Plink' then begin
552 RdbSSH
[GS_Plink
].Checked
:=True;
559 * Create a custom page for the core.autocrlf setting.
562 CRLFPage
:=CreateCustomPage(
564 'Configuring the line ending conversions',
565 'How should Git treat line endings in text files?'
567 PrevPageID
:=CRLFPage
.ID
;
570 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
571 with RdbCRLF
[GC_CRLFAlways
] do begin
572 Parent
:=CRLFPage
.Surface
;
573 Caption
:='Checkout Windows-style, commit Unix-style line endings';
578 Font
.Style
:=[fsBold
];
582 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
583 with LblCRLFAlways
do begin
584 Parent
:=CRLFPage
.Surface
;
586 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
587 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
588 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
596 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
597 with RdbCRLF
[GC_LFOnly
] do begin
598 Parent
:=CRLFPage
.Surface
;
599 Caption
:='Checkout as-is, commit Unix-style line endings';
604 Font
.Style
:=[fsBold
];
608 LblLFOnly
:=TLabel
.Create(CRLFPage
);
609 with LblLFOnly
do begin
610 Parent
:=CRLFPage
.Surface
;
612 'Git will not perform any conversion when checking out text files. When' + #
13 +
613 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
614 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
622 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
623 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
624 Parent
:=CRLFPage
.Surface
;
625 Caption
:='Checkout as-is, commit as-is';
630 Font
.Style
:=[fsBold
];
634 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
635 with LblCRLFCommitAsIs
do begin
636 Parent
:=CRLFPage
.Surface
;
638 'Git will not perform any conversions when checking out or committing' + #
13 +
639 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
640 'projects ("core.autocrlf" is set to "false").';
647 // Restore the setting chosen during a previous install
.
648 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
649 if Data
='LFOnly' then begin
650 RdbCRLF
[GC_LFOnly
].Checked
:=True;
651 end else if Data
='CRLFAlways' then begin
652 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
653 end else if Data
='CRLFCommitAsIs' then begin
654 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
658 * Create a custom page for finding the processes that lock a module.
661 ProcessesPage
:=CreateCustomPage(
663 'Replacing in-use files',
664 'The following applications use files that need to be replaced, please close them.'
667 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
668 with ProcessesListBox
do begin
669 Parent
:=ProcessesPage
.Surface
;
670 Width
:=ProcessesPage
.SurfaceWidth
;
671 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
674 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
675 with ProcessesRefresh
do begin
677 Width
:=WizardForm
.CancelButton
.Width
;
678 Height
:=WizardForm
.CancelButton
.Height
;
679 Top
:=WizardForm
.CancelButton
.Top
;
680 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
682 OnClick
:=@RefreshProcessList
;
685 // This button
is only used by the uninstaller
.
688 // Initially hide the Refresh button
, show it when the process page becomes current
.
689 ProcessesRefresh
.Hide
;
692 function ShouldSkipPage(PageID
:Integer):Boolean;
694 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
695 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
696 RefreshProcessList(NIL);
697 Result
:=(GetArrayLength(Processes
)=0);
703 procedure CurPageChanged(CurPageID
:Integer);
707 if CurPageID
=wpSelectDir
then begin
708 if not IsDirWritable(WizardDirValue
) then begin
709 // If the default directory
is not writable
, choose another default that most likely
is.
710 // This will be checked later again when the user clicks
"Next".
711 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
715 // Uncheck the console font option by default
.
716 if CurPageID
=wpSelectComponents
then begin
717 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
718 if WizardForm
.ComponentsList
.ItemCaption
[i
]='{#COMP_CONSOLE_FONT}' then begin
719 WizardForm
.ComponentsList
.Checked
[i
]:=False;
725 // Show the
"Refresh" button only on the processes page
.
726 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
727 ProcessesRefresh
.Show
;
729 ProcessesRefresh
.Hide
;
733 function NextButtonClick(CurPageID
:Integer):Boolean;
736 Version
:TWindowsVersion
;
740 if CurPageID
=wpSelectDir
then begin
741 if not IsDirWritable(WizardDirValue
) then begin
743 'The specified installation directory does not seem to be writable. ' +
744 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
753 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
754 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
755 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
756 if not Result
then begin
757 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
759 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
760 // It would have been nicer
to just disable the
"Next" button
, but the
761 // WizardForm
exports the button just
read-only
.
762 for i
:=0 to GetArrayLength(Processes
)-1 do begin
763 if not Processes
[i
].Restartable
then begin
764 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
770 Result
:=(GetArrayLength(Processes
)=0);
772 if not Result
then begin
773 GetWindowsVersionEx(Version
);
774 if Version
.Major
>=6 then begin
776 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
777 'Are you sure you want to continue?',
783 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
784 'Are you sure you want to continue anyway?',
793 procedure CurStepChanged(CurStep
:TSetupStep
);
795 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
796 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
802 if CurStep
=ssInstall
then begin
803 // Shutdown locking processes just before the actual installation starts
.
804 if SessionHandle
>0 then try
805 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
807 Log('Line {#__LINE__}: RmShutdown not supported.');
813 // Make sure the code below
is only executed just after the actual installation finishes
.
814 if CurStep
<>ssPostInstall
then begin
818 AppDir
:=ExpandConstant('{app}');
821 Bind the imported function addresses
825 DllPath
:=ExpandConstant('{app}\bin;{sys}');
827 // Load the list
of images from a
text file.
828 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
829 if LoadStringsFromFile(FileName
,ImageNames
) then begin
830 Count
:=GetArrayLength(ImageNames
)-1;
831 for i
:=0 to Count
do begin
832 FileName
:=AppDir
+'\'+ImageNames[i];
833 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
834 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
839 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
846 // Load the built-ins from a text file.
847 FileName:=AppDir+'\
{#APP_BUILTINS}';
848 if LoadStringsFromFile(FileName,BuiltIns) then begin
849 Count:=GetArrayLength(BuiltIns)-1;
851 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
852 for i:=0 to Count do begin
853 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
854 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
855 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
859 // Create built
-ins
as aliases
for git
.exe
.
860 for i
:=0 to Count
do begin
861 FileName
:=AppDir
+'\'+BuiltIns[i];
863 // Delete any existing built-in.
864 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
865 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
870 // This will throw an exception on pre-Win2k systems.
871 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
874 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
877 if not LinkCreated then begin
878 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
879 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
880 // This is not a critical error, Git could basically be used without the
881 // aliases for built-ins, so we continue.
886 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
887 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
889 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
890 FileName:=AppDir+'\bin
\'+FindRec
.name
;
891 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
892 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
895 until not FindNext(FindRec
);
899 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
900 MsgBox(Msg
,mbError
,MB_OK
);
902 // This
is not a critical error
, Git could basically be used without the
903 // aliases
for built
-ins
, so we continue
.
910 if RdbCRLF
[GC_LFOnly
].checked
then begin
911 Cmd
:='core.autocrlf input';
912 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
913 Cmd
:='core.autocrlf true';
915 Cmd
:='core.autocrlf false';
917 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
918 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
919 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
920 MsgBox(Msg
,mbError
,MB_OK
);
922 // This
is not a critical error
, the user can probably fix it manually
,
927 Modify the environment
929 This must happen no later than ssPostInstall to make
930 "ChangesEnvironment=yes" not happend before the change!
933 FileName
:=AppDir
+'\setup.ini';
935 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
936 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
937 if (GetArrayLength(EnvSSH
)=1) and
938 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
939 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
940 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
941 MsgBox(Msg
,mbError
,MB_OK
);
943 // This
is not a critical error
, the user can probably fix it manually
,
948 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
949 if (GetArrayLength(EnvSSH
)=1) and
950 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
951 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
952 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
953 MsgBox(Msg
,mbError
,MB_OK
);
955 // This
is not a critical error
, the user can probably fix it manually
,
960 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
961 SetArrayLength(EnvSSH
,1);
962 EnvSSH
[0]:=EdtPlink
.Text;
964 // Set GIT_SSH
as specified by the user
.
965 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
966 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
967 MsgBox(Msg
,mbError
,MB_OK
);
969 // This
is not a critical error
, the user can probably fix it manually
,
973 // Mark that we have changed GIT_SSH by writing its value
to a
file.
974 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
975 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
976 MsgBox(Msg
,mbError
,MB_OK
);
978 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
982 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
983 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
984 MsgBox(Msg
,mbError
,MB_OK
);
986 // This
is not a critical error
, the user can probably fix it manually
,
990 // Mark that we have changed SVN_SSH by writing its value
to a
file.
991 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
992 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
993 MsgBox(Msg
,mbError
,MB_OK
);
995 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1000 // Get the current user
's directories in PATH.
1001 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1003 // First, remove the installation directory from PATH in any case.
1004 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1005 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1010 // Delete HOME if a previous installation modified it.
1011 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1012 if (GetArrayLength(EnvHome)=1) and
1013 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1014 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1015 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1016 MsgBox(Msg,mbError,MB_OK);
1018 // This is not a critical error, the user can probably fix it manually,
1023 // Modify the PATH variable as requested by the user.
1024 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1025 i:=GetArrayLength(EnvPath);
1026 SetArrayLength(EnvPath,i+1);
1028 // List \cmd before \bin so \cmd has higher priority and programs in
1029 // there will be called in favor of those in \bin.
1030 EnvPath[i]:=AppDir+'\cmd
';
1032 if RdbPath[GP_CmdTools].Checked then begin
1033 SetArrayLength(EnvPath,i+2);
1034 EnvPath[i+1]:=AppDir+'\bin
';
1036 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1037 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1038 i:=GetArrayLength(EnvHome);
1039 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1040 SetArrayLength(EnvHome,1);
1041 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1042 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1043 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1044 MsgBox(Msg,mbError,MB_OK);
1046 // This is not a critical error, the user can probably fix it manually,
1050 // Mark that we have changed HOME.
1051 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1052 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1053 MsgBox(Msg,mbError,MB_OK);
1055 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1062 // Set the current user's PATH directories
.
1063 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1064 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1065 MsgBox(Msg
,mbError
,MB_OK
);
1067 // This
is not a critical error
, the user can probably fix it manually
,
1072 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1075 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1076 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1077 FileName
:=AppDir
+'\etc\git.ico';
1079 if IsComponentSelected('icons\quicklaunch') then begin
1081 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1085 , '%HOMEDRIVE%%HOMEPATH%'
1091 if IsComponentSelected('icons\desktop') then begin
1093 GetShellFolder('desktop')+'\Git Bash.lnk'
1097 , '%HOMEDRIVE%%HOMEPATH%'
1104 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1105 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1106 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1108 AppDir
+'\Git Bash.lnk'
1119 Create the Windows Explorer integrations
1122 if IsAdminLoggedOn
then begin
1123 RootKey
:=HKEY_LOCAL_MACHINE
;
1125 RootKey
:=HKEY_CURRENT_USER
;
1128 if IsComponentSelected('ext\reg\shellhere') then begin
1129 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
1130 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','','"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"')) then begin
1131 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1132 MsgBox(Msg
,mbError
,MB_OK
);
1134 // This
is not a critical error
, the user can probably fix it manually
,
1139 if IsComponentSelected('ext\reg\guihere') then begin
1140 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
1141 (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
1142 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1143 MsgBox(Msg
,mbError
,MB_OK
);
1145 // This
is not a critical error
, the user can probably fix it manually
,
1150 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1151 if IsComponentSelected('ext\cheetah') then begin
1152 DeleteContextMenuEntries
;
1154 if isWin64
then begin
1155 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1157 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1159 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1160 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1165 Restart any processes that were shut down via the Restart Manager
1168 if SessionHandle
>0 then try
1169 RmRestart(SessionHandle
,0,0);
1170 RmEndSession(SessionHandle
);
1172 Log('Line {#__LINE__}: RmRestart not supported.');
1176 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1180 // Git Path options
.
1182 if RdbPath
[GP_BashOnly
].Checked
then begin
1184 end else if RdbPath
[GP_Cmd
].Checked
then begin
1186 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1189 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1193 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1195 end else if RdbSSH
[GS_Plink
].Checked
then begin
1198 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1200 // Line ending conversion options
.
1202 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1204 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1206 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1207 Data
:='CRLFCommitAsIs';
1209 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1216 function InitializeUninstall
:Boolean;
1220 ExitButton
,RefreshButton
:TButton
;
1224 Form
:=CreateCustomForm
;
1226 Form
.Caption
:='Git Uninstall: Removing in-use files';
1227 Form
.ClientWidth
:=ScaleX(500);
1228 Form
.ClientHeight
:=ScaleY(256);
1231 Info
:=TLabel
.Create(Form
);
1237 Caption
:='The following applications use files that need to be removed, please close them.';
1240 ContinueButton
:=TButton
.Create(Form
);
1241 with ContinueButton
do begin
1243 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1244 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1247 Caption
:='Continue';
1251 ExitButton
:=TButton
.Create(Form
);
1252 with ExitButton
do begin
1254 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1255 Top
:=ContinueButton
.Top
;
1259 ModalResult
:=mrCancel
;
1263 RefreshButton
:=TButton
.Create(Form
);
1264 with RefreshButton
do begin
1267 Top
:=ExitButton
.Top
;
1271 OnClick
:=@RefreshProcessList
;
1274 ProcessesListBox
:=TListBox
.Create(Form
);
1275 with ProcessesListBox
do begin
1278 Top
:=Info
.Top
+Info
.Height
+11;
1279 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1280 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1283 Form
.ActiveControl
:=ContinueButton
;
1285 RefreshProcessList(NIL);
1286 if GetArrayLength(Processes
)>0 then begin
1287 // Now that these dialogs are going
to be shown
, we should probably
1288 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1289 // unfortunately that
is not possible
with Inno Setup currently
.
1290 Result
:=(Form
.ShowModal()=mrOk
);
1292 // Note
: The number
of processes might have changed during a refresh
.
1293 if Result
and (GetArrayLength(Processes
)>0) then begin
1295 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1296 'Are you sure you want to continue anyway?',
1309 // Even though the name
of this
function suggests otherwise most
of the
1310 // code below
is only executed right before the actual uninstallation
.
1311 // This happens because
of the
if-guard right
in the beginning
of this
1313 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1315 AppDir
,FileName
,Msg
:String;
1316 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1319 if CurUninstallStep
<>usUninstall
then begin
1323 // Reset the console
font (the FontType
is reset
in the Registry section
).
1324 if IsComponentInstalled('consolefont') then begin
1325 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1326 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1327 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1328 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1333 Modify the environment
1335 This must happen no later than usUninstall to make
1336 "ChangesEnvironment=yes" not happend before the change!
1339 AppDir
:=ExpandConstant('{app}');
1340 FileName
:=AppDir
+'\setup.ini';
1342 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1343 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1344 if (GetArrayLength(EnvSSH)=1) and
1345 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1346 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1347 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1348 MsgBox(Msg,mbError,MB_OK);
1350 // This is not a critical error, the user can probably fix it manually,
1355 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1356 if (GetArrayLength(EnvSSH)=1) and
1357 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1358 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1359 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1360 MsgBox(Msg,mbError,MB_OK);
1362 // This is not a critical error, the user can probably fix it manually,
1367 // Get the current user's directories
in PATH
.
1368 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1370 // Remove the installation directory from PATH
in any
case, even
if it
1371 // was
not added by the installer
.
1372 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1373 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1378 // Reset the current user
's directories in PATH.
1379 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1380 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1381 MsgBox(Msg,mbError,MB_OK);
1383 // This is not a critical error, the user can probably fix it manually,
1387 // Reset the current user's HOME
if we modified it
.
1388 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1389 if (GetArrayLength(EnvHome
)=1) and
1390 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1391 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1392 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1393 MsgBox(Msg
,mbError
,MB_OK
);
1395 // This
is not a critical error
, the user can probably fix it manually
,
1400 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1401 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1402 MsgBox(Msg
,mbError
,MB_OK
);
1404 // This
is not a critical error
, the user can probably fix it manually
,
1409 Delete the Windows Explorer integrations
1412 DeleteContextMenuEntries
;
1414 if isWin64
then begin
1415 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1417 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1419 if FileExists(FileName
) then begin
1420 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1421 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1422 MsgBox(Msg
,mbError
,MB_OK
);
1426 if not DeleteFile(FileName
) then begin
1427 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1428 MsgBox(Msg
,mbError
,MB_OK
);