1 ; Uncomment the line below to be able to compile the script from within the IDE.
2 ;#define COMPILE_FROM_IDE
5 #ifdef COMPILE_FROM_IDE
6 #define APP_VERSION
'Snapshot'
8 #define APP_VERSION
'%APPVERSION%'
10 #define APP_URL
'http://msysgit.github.io/'
11 #define APP_BUILTINS
'etc\fileList-builtins.txt'
12 #define APP_BINDIMAGE
'etc\fileList-bindimage.txt'
14 #define PLINK_PATH_ERROR_MSG
'Please enter a valid path to a Plink executable.'
16 #define DROP_HANDLER_GUID
'{{86C86720-42A0-1069-A2E8-08002B30309D}'
20 Compression
=lzma2
/ultra
21 LZMAUseSeparateProcess
=yes
22 OutputBaseFilename
={#APP_NAME+'-'+APP_VERSION}
23 OutputDir
={#GetEnv('USERPROFILE')}
25 #ifdef COMPILE_FROM_IDE
26 SourceDir
={#GetEnv('TEMP')}\WinGit
32 AppPublisher
=The Git Development Community
33 AppPublisherURL
={#APP_URL}
34 AppVersion
={#APP_VERSION}
35 ChangesEnvironment
=yes
37 DefaultDirName
={pf}\
{#APP_NAME}
39 DefaultGroupName
={#APP_NAME}
40 DisableProgramGroupPage
=auto
42 InfoBeforeFile
=gpl
-2.0.rtf
43 PrivilegesRequired
=none
44 UninstallDisplayIcon
={app}\etc\git
.ico
45 #ifndef COMPILE_FROM_IDE
46 #
if Pos('-',APP_VERSION
)>0
47 VersionInfoVersion
={#Copy(APP_VERSION,1,Pos('-',APP_VERSION)-1)}
49 VersionInfoVersion
={#APP_VERSION}
54 SetupIconFile
=etc\git
.ico
55 WizardImageBackColor
=clWhite
57 WizardImageFile
=git
.bmp
58 WizardSmallImageFile
=gitsmall
.bmp
61 ; Define a custom type to avoid getting the three default types.
62 Name
: default
; Description
: Default installation
; Flags
: iscustom
65 Name
: icons
; Description
: Additional icons
66 Name
: icons\quicklaunch
; Description
: In the Quick Launch
67 Name
: icons\desktop
; Description
: On the Desktop
68 Name
: ext
; Description
: Windows Explorer integration
; Types
: default
69 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: default
70 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: default
71 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: default
72 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: default
73 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: default
74 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: default
75 Name
: consolefont
; Description
: Use a TrueType font
in all console
windows (not only
for Git Bash
)
78 ; Install files that might be in use during setup under a different name.
79 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
80 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
82 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; AfterInstall
: DeleteFromVirtualStore
83 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion; AfterInstall
: DeleteFromVirtualStore
86 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
87 Name
: {group}\Git Bash
; Filename
: {syswow64}\cmd
.exe
; Parameters
: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; OnlyBelowVersion
: 6.0
88 Name
: {group}\Git Bash
; Filename
: {app}\bin\sh
.exe
; Parameters
: "--login -i"; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; MinVersion
: 6.0
91 BeveledLabel
={#APP_URL}
92 SetupAppTitle
={#APP_NAME} Setup
93 SetupWindowTitle
={#APP_NAME} Setup
96 ; There is no "Console" key in HKLM.
97 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
98 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
99 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
100 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
102 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
103 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
104 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
105 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
107 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
108 ; is a member of the local Administrators group or not (see the "Check" argument).
110 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
111 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
112 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
113 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
114 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
115 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
116 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
118 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
119 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
120 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
121 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
122 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
123 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
125 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
126 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
127 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
128 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
129 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
130 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
132 ; Associate .sh extension with sh.exe so those files are double-clickable,
133 ; startable from cmd.exe, and when files are dropped on them they are passed
134 ; as arguments to the script.
136 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
137 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
138 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
139 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
; OnlyBelowVersion
: 6.0
140 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: """{app}\bin\sh.exe"" ""--login"" ""%1"" %*"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
; MinVersion
: 6.0
141 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
142 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
144 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
145 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
146 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
147 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
; OnlyBelowVersion
: 6.0
148 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: """{app}\bin\sh.exe"" ""--login"" ""%1"" %*"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
; MinVersion
: 6.0
149 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
150 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
153 ; Delete the built-ins.
154 Type: files; Name
: {app}\bin\git
-*.exe
155 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
156 Type: files; Name
: {app}\libexec\git
-core\git
.exe
158 ; Delete any (temporary) git-cheetah files.
159 Type: files; Name
: {app}\git
-cheetah\
*.*
161 ; Delete any manually created shortcuts.
162 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
163 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
164 Type: files; Name
: {app}\Git Bash
.lnk
166 ; Delete a home directory inside the msysGit directory.
167 Type: dirifempty; Name
: {app}\home\
{username}
168 Type: dirifempty; Name
: {app}\home
171 #include
"helpers.inc.iss"
172 #include
"environment.inc.iss"
173 #include
"putty.inc.iss"
174 #include
"modules.inc.iss"
176 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
178 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
180 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
183 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
184 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
196 // Git line ending conversion options
.
199 GC_CRLFCommitAsIs
= 3;
201 // BindImageEx API constants
.
202 BIND_NO_BOUND_IMPORTS
= $00000001;
203 BIND_NO_UPDATE
= $00000002;
204 BIND_ALL_IMAGES
= $00000004;
205 BIND_CACHE_IMPORT_DLLS
= $00000008;
208 // Wizard page
and variables
for the Path options
.
209 PathPage
:TWizardPage
;
210 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
212 // Wizard page
and variables
for the SSH options
.
213 PuTTYPage
:TWizardPage
;
214 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
217 // Wizard page
and variables
for the line ending conversion options
.
218 CRLFPage
:TWizardPage
;
219 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
221 // Wizard page
and variables
for the processes page
.
223 Processes
:ProcessList
;
224 ProcessesPage
:TWizardPage
;
225 ProcessesListBox
:TListBox
;
226 ProcessesRefresh
,ContinueButton
:TButton
;
229 Specific helper functions
232 procedure BrowseForPuTTYFolder(Sender
:TObject
);
237 'Please select a Plink executable'
239 , ExtractFilePath(EdtPlink
.Text)
240 , 'Executable Files|*.exe'
244 if IsPlinkExecutable(Name
) then begin
246 RdbSSH
[GS_Plink
].Checked
:=True;
248 // This
message box only gets triggered on interactive use
, so it
249 // does
not need
to be suppressible
for silent installations
.
250 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
255 procedure DeleteContextMenuEntries
;
257 AppDir
,Command
,Msg
:String;
261 AppDir
:=ExpandConstant('{app}');
263 if IsAdminLoggedOn
then begin
264 RootKey
:=HKEY_LOCAL_MACHINE
;
266 RootKey
:=HKEY_CURRENT_USER
;
269 SetArrayLength(Keys
,4);
270 Keys
[0]:='SOFTWARE\Classes\Directory\shell\git_shell';
271 Keys
[1]:='SOFTWARE\Classes\Directory\Background\shell\git_shell';
272 Keys
[2]:='SOFTWARE\Classes\Directory\shell\git_gui';
273 Keys
[3]:='SOFTWARE\Classes\Directory\Background\shell\git_gui';
275 for i
:=0 to Length(Keys
)-1 do begin
277 RegQueryStringValue(RootKey
,Keys
[i
]+'\command','',Command
);
278 if Pos(AppDir
,Command
)>0 then begin
279 if not RegDeleteKeyIncludingSubkeys(RootKey
,Keys
[i
]) then begin
280 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash / GUI Here" shell extension.';
282 // This
is not a critical error
, so just notify the user
and continue
.
283 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
290 procedure RefreshProcessList(Sender
:TObject
);
292 Version
:TWindowsVersion
;
293 Modules
:TArrayOfString
;
294 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
297 ManualClosingRequired
:Boolean;
299 GetWindowsVersionEx(Version
);
301 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
302 if Version
.Major
>=6 then begin
303 SetArrayLength(Modules
,5);
304 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
305 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
306 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
307 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
308 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
309 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
311 SetArrayLength(Modules
,3);
312 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
313 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
314 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
315 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
317 SetArrayLength(Modules
,2);
318 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
319 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
320 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
322 // Misuse the
"Restartable" flag
to indicate which processes are required
323 // to be closed before setup can continue
, and which just should be closed
324 // in order
to make changes take effect immediately
.
325 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
326 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
327 Processes
[i
]:=ProcsCloseRequired
[i
];
328 Processes
[i
].Restartable
:=False;
330 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
331 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
332 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
336 ManualClosingRequired
:=False;
338 ProcessesListBox
.Items
.Clear
;
339 if (Sender
=NIL) or (SessionHandle
>0) then begin
340 for i
:=0 to GetArrayLength(Processes
)-1 do begin
341 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
342 if Processes
[i
].Restartable
then begin
343 Caption
:=Caption
+', closing is optional';
345 Caption
:=Caption
+', closing is required';
346 ManualClosingRequired
:=True;
348 Caption
:=Caption
+')';
349 ProcessesListBox
.Items
.Append(Caption
);
353 if ContinueButton
<>NIL then begin
354 ContinueButton
.Enabled
:=not ManualClosingRequired
;
358 procedure SetAndMarkEnvString(Name
,Value
:String;Expandable
:Boolean);
363 SetArrayLength(Env
,1);
366 // Try to set the variable
as specified by the user
.
367 if not SetEnvStrings(Name
,Env
,Expandable
,IsAdminLoggedOn
,True) then begin
368 Msg
:='Line {#__LINE__}: Unable to set the '+Name
+' environment variable.';
370 // This
is not a critical error
, so just notify the user
and continue
.
371 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
374 // Mark that we have changed the variable by writing its value
to a
file.
375 FileName
:=ExpandConstant('{app}')+'\setup.ini';
376 if not SetIniString('Environment',Name
,Value
,FileName
) then begin
377 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
379 // This
is not a critical error
, so just notify the user
and continue
.
380 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
386 procedure DeleteMarkedEnvString(Name
:String);
391 Env
:=GetEnvStrings(Name
,IsAdminLoggedOn
);
392 FileName
:=ExpandConstant('{app}')+'\setup.ini';
394 if (GetArrayLength(Env
)=1) and
395 (CompareStr(RemoveQuotes(Env
[0]),GetIniString('Environment',Name
,'',FileName
))=0) then begin
396 if not SetEnvStrings(Name
,[],False,IsAdminLoggedOn
,True) then begin
397 Msg
:='Line {#__LINE__}: Unable to delete the '+Name
+' environment variable.';
399 // This
is not a critical error
, so just notify the user
and continue
.
400 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
407 Setup event functions
410 function InitializeSetup
:Boolean;
416 procedure InitializeWizard
;
419 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
420 LblOpenSSH
,LblPlink
:TLabel
;
421 PuTTYSessions
,EnvSSH
:TArrayOfString
;
422 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
427 PrevPageID
:=wpSelectProgramGroup
;
430 * Create a custom page for modifying the environment.
433 PathPage
:=CreateCustomPage(
435 , 'Adjusting your PATH environment'
436 , 'How would you like to use Git from the command line?'
438 PrevPageID
:=PathPage
.ID
;
441 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
442 with RdbPath
[GP_BashOnly
] do begin
443 Parent
:=PathPage
.Surface
;
444 Caption
:='Use Git from Git Bash only';
449 Font
.Style
:=[fsBold
];
453 LblGitBash
:=TLabel
.Create(PathPage
);
454 with LblGitBash
do begin
455 Parent
:=PathPage
.Surface
;
457 'This is the safest choice as your PATH will not be modified at all. You will only be' + #
13 +
458 'able to use the Git command line tools from Git Bash.';
466 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
467 with RdbPath
[GP_Cmd
] do begin
468 Parent
:=PathPage
.Surface
;
469 Caption
:='Use Git from the Windows Command Prompt';
474 Font
.Style
:=[fsBold
];
477 LblGitCmd
:=TLabel
.Create(PathPage
);
478 with LblGitCmd
do begin
479 Parent
:=PathPage
.Surface
;
481 'This option is considered safe as it only adds some minimal Git wrappers to your' + #
13 +
482 'PATH to avoid cluttering your environment with optional Unix tools. You will be' + #
13 +
483 'able to use Git from both Git Bash and the Windows Command Prompt.';
491 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
492 with RdbPath
[GP_CmdTools
] do begin
493 Parent
:=PathPage
.Surface
;
494 Caption
:='Use Git and optional Unix tools from the Windows Command Prompt';
499 Font
.Style
:=[fsBold
];
502 LblGitCmdTools
:=TLabel
.Create(PathPage
);
503 with LblGitCmdTools
do begin
504 Parent
:=PathPage
.Surface
;
505 Caption
:='Both Git and the optional Unix tools will be added to your PATH.';
511 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
512 with LblGitCmdToolsWarn
do begin
513 Parent
:=PathPage
.Surface
;
515 'Warning: This will override Windows tools like "find" and "sort". Only' + #
13 +
516 'use this option if you understand the implications.';
522 Font
.Style
:=[fsBold
];
525 // Restore the setting chosen during a previous install
.
526 Data
:=GetPreviousData('Path Option','BashOnly');
528 // Use settings from the user provided INF
.
529 if ShouldLoadInf
then begin
530 Data
:=LoadInfString('Setup','PathOption','BashOnly');
533 if Data
='BashOnly' then begin
534 RdbPath
[GP_BashOnly
].Checked
:=True;
535 end else if Data
='Cmd' then begin
536 RdbPath
[GP_Cmd
].Checked
:=True;
537 end else if Data
='CmdTools' then begin
538 RdbPath
[GP_CmdTools
].Checked
:=True;
542 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
543 * if at least one PuTTY session is found in the Registry.
546 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
547 PuTTYPage
:=CreateCustomPage(
549 , 'Choosing the SSH executable'
550 , 'Which Secure Shell client program would you like Git to use?'
552 PrevPageID
:=PuTTYPage
.ID
;
555 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
556 with RdbSSH
[GS_OpenSSH
] do begin
557 Parent
:=PuTTYPage
.Surface
;
558 Caption
:='Use OpenSSH';
563 Font
.Style
:=[fsBold
];
567 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
568 with LblOpenSSH
do begin
569 Parent
:=PuTTYPage
.Surface
;
571 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
572 'environment variables will not be modified.';
580 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
581 with RdbSSH
[GS_Plink
] do begin
582 Parent
:=PuTTYPage
.Surface
;
583 Caption
:='Use (Tortoise)Plink';
588 Font
.Style
:=[fsBold
];
591 LblPlink
:=TLabel
.Create(PuTTYPage
);
592 with LblPlink
do begin
593 Parent
:=PuTTYPage
.Surface
;
595 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
596 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
597 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
598 'variables will be adjusted to point to the following executable:';
604 EdtPlink
:=TEdit
.Create(PuTTYPage
);
605 with EdtPlink
do begin
606 Parent
:=PuTTYPage
.Surface
;
608 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
609 if (GetArrayLength(EnvSSH
)=1) and IsPlinkExecutable(EnvSSH
[0]) then begin
612 if not FileExists(Text) then begin
613 Text:=GetPreviousData('Plink Path','');
615 if not FileExists(Text) then begin
616 Text:=GuessPlinkExecutable
;
618 if not FileExists(Text) then begin
627 BtnPlink
:=TButton
.Create(PuTTYPage
);
628 with BtnPlink
do begin
629 Parent
:=PuTTYPage
.Surface
;
631 OnClick
:=@BrowseForPuTTYFolder
;
638 // Restore the setting chosen during a previous install
.
639 Data
:=GetPreviousData('SSH Option','OpenSSH');
641 // Use settings from the user provided INF
.
642 if ShouldLoadInf
then begin
643 Data
:=LoadInfString('Setup','SSHOption','OpenSSH');
646 if Data
='OpenSSH' then begin
647 RdbSSH
[GS_OpenSSH
].Checked
:=True;
648 end else if Data
='Plink' then begin
649 RdbSSH
[GS_Plink
].Checked
:=True;
656 * Create a custom page for the core.autocrlf setting.
659 CRLFPage
:=CreateCustomPage(
661 , 'Configuring the line ending conversions'
662 , 'How should Git treat line endings in text files?'
664 PrevPageID
:=CRLFPage
.ID
;
667 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
668 with RdbCRLF
[GC_CRLFAlways
] do begin
669 Parent
:=CRLFPage
.Surface
;
670 Caption
:='Checkout Windows-style, commit Unix-style line endings';
675 Font
.Style
:=[fsBold
];
679 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
680 with LblCRLFAlways
do begin
681 Parent
:=CRLFPage
.Surface
;
683 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
684 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
685 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
693 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
694 with RdbCRLF
[GC_LFOnly
] do begin
695 Parent
:=CRLFPage
.Surface
;
696 Caption
:='Checkout as-is, commit Unix-style line endings';
701 Font
.Style
:=[fsBold
];
705 LblLFOnly
:=TLabel
.Create(CRLFPage
);
706 with LblLFOnly
do begin
707 Parent
:=CRLFPage
.Surface
;
709 'Git will not perform any conversion when checking out text files. When' + #
13 +
710 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
711 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
719 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
720 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
721 Parent
:=CRLFPage
.Surface
;
722 Caption
:='Checkout as-is, commit as-is';
727 Font
.Style
:=[fsBold
];
731 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
732 with LblCRLFCommitAsIs
do begin
733 Parent
:=CRLFPage
.Surface
;
735 'Git will not perform any conversions when checking out or committing' + #
13 +
736 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
737 'projects ("core.autocrlf" is set to "false").';
744 // Restore the setting chosen during a previous install
.
745 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
747 // Use settings from the user provided INF
.
748 if ShouldLoadInf
then begin
749 Data
:=LoadInfString('Setup','CRLFOption','CRLFAlways');
752 if Data
='LFOnly' then begin
753 RdbCRLF
[GC_LFOnly
].Checked
:=True;
754 end else if Data
='CRLFAlways' then begin
755 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
756 end else if Data
='CRLFCommitAsIs' then begin
757 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
761 * Create a custom page for finding the processes that lock a module.
764 ProcessesPage
:=CreateCustomPage(
766 , 'Replacing in-use files'
767 , 'The following applications use files that need to be replaced, please close them.'
770 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
771 with ProcessesListBox
do begin
772 Parent
:=ProcessesPage
.Surface
;
773 Width
:=ProcessesPage
.SurfaceWidth
;
774 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
777 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
778 with ProcessesRefresh
do begin
780 Width
:=WizardForm
.CancelButton
.Width
;
781 Height
:=WizardForm
.CancelButton
.Height
;
782 Top
:=WizardForm
.CancelButton
.Top
;
783 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
785 OnClick
:=@RefreshProcessList
;
788 // This button
is only used by the uninstaller
.
791 // Initially hide the Refresh button
, show it when the process page becomes current
.
792 ProcessesRefresh
.Hide
;
795 function ShouldSkipPage(PageID
:Integer):Boolean;
797 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
798 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
799 RefreshProcessList(NIL);
800 Result
:=(GetArrayLength(Processes
)=0);
806 procedure CurPageChanged(CurPageID
:Integer);
808 if CurPageID
=wpInfoBefore
then begin
809 if WizardForm
.NextButton
.Enabled
then begin
810 // By default
, do not show a blinking cursor
for InfoBeforeFile
.
811 WizardForm
.ActiveControl
:=WizardForm
.NextButton
;
813 end else if CurPageID
=wpSelectDir
then begin
814 if not IsDirWritable(WizardDirValue
) then begin
815 // If the default directory
is not writable
, choose another default that most likely
is.
816 // This will be checked later again when the user clicks
"Next".
817 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
819 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
820 // Show the
"Refresh" button only on the processes page
.
821 ProcessesRefresh
.Show
;
823 ProcessesRefresh
.Hide
;
827 function NextButtonClick(CurPageID
:Integer):Boolean;
830 Version
:TWindowsVersion
;
832 // On a silent install
, if your NextButtonClick
function returns
False
833 // prior
to installation starting
, Setup will exit automatically
.
836 if CurPageID
=wpSelectDir
then begin
837 if not IsDirWritable(WizardDirValue
) then begin
839 'The specified installation directory does not seem to be writable. ' +
840 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
850 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
851 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
852 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
853 if not Result
then begin
854 SuppressibleMsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
,IDOK
);
856 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
857 // It would have been nicer
to just disable the
"Next" button
, but the
858 // WizardForm
exports the button just
read-only
.
859 for i
:=0 to GetArrayLength(Processes
)-1 do begin
860 if not Processes
[i
].Restartable
then begin
862 'Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".'
872 Result
:=(GetArrayLength(Processes
)=0);
874 if not Result
then begin
875 GetWindowsVersionEx(Version
);
876 if Version
.Major
>=6 then begin
877 Result
:=(SuppressibleMsgBox(
878 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
879 'Are you sure you want to continue?'
885 Result
:=(SuppressibleMsgBox(
886 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
887 'Are you sure you want to continue anyway?'
897 procedure CurStepChanged(CurStep
:TSetupStep
);
899 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
900 BuiltIns
,ImageNames
,EnvPath
,EnvHome
:TArrayOfString
;
905 Version
:TWindowsVersion
;
907 if CurStep
=ssInstall
then begin
908 // Shutdown locking processes just before the actual installation starts
.
909 if SessionHandle
>0 then try
910 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
912 Log('Line {#__LINE__}: RmShutdown not supported.');
918 // Make sure the code below
is only executed just after the actual installation finishes
.
919 if CurStep
<>ssPostInstall
then begin
923 AppDir
:=ExpandConstant('{app}');
926 Bind the imported function addresses
930 DllPath
:=ExpandConstant('{app}\bin;{sys}');
932 // Load the list
of images from a
text file.
933 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
934 if LoadStringsFromFile(FileName
,ImageNames
) then begin
935 Count
:=GetArrayLength(ImageNames
)-1;
936 for i
:=0 to Count
do begin
937 FileName
:=AppDir
+'\'+ImageNames[i];
938 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
939 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
944 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
951 // Load the built-ins from a text file.
952 FileName:=AppDir+'\
{#APP_BUILTINS}';
953 if LoadStringsFromFile(FileName,BuiltIns) then begin
954 Count:=GetArrayLength(BuiltIns)-1;
956 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
957 for i:=0 to Count do begin
958 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
959 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
960 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
964 // Create built
-ins
as aliases
for git
.exe
.
965 for i
:=0 to Count
do begin
966 FileName
:=AppDir
+'\'+BuiltIns[i];
968 // Delete any existing built-in.
969 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
970 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
975 // This will throw an exception on pre-Win2k systems.
976 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
979 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
982 if not LinkCreated then begin
983 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
984 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
985 // This is not a critical error, Git could basically be used without the
986 // aliases for built-ins, so we continue.
991 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
992 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
994 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
995 FileName:=AppDir+'\bin
\'+FindRec
.name
;
996 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
997 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
1000 until not FindNext(FindRec
);
1004 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
1006 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
1007 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
1008 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1016 if RdbCRLF
[GC_LFOnly
].checked
then begin
1017 Cmd
:='core.autocrlf input';
1018 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
1019 Cmd
:='core.autocrlf true';
1021 Cmd
:='core.autocrlf false';
1023 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
1024 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
1025 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
1027 // This
is not a critical error
, so just notify the user
and continue
.
1028 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1033 Modify the environment
1035 This must happen no later than ssPostInstall to make
1036 "ChangesEnvironment=yes" not happend before the change!
1039 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
1040 DeleteMarkedEnvString('GIT_SSH');
1041 DeleteMarkedEnvString('SVN_SSH');
1043 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
1044 SetAndMarkEnvString('GIT_SSH',EdtPlink
.Text,True);
1045 SetAndMarkEnvString('SVN_SSH',EdtPlink
.Text,True);
1048 // Get the current user
's directories in PATH.
1049 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1051 // First, remove the installation directory from PATH in any case.
1052 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1053 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1058 // Modify the PATH variable as requested by the user.
1059 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1060 i:=GetArrayLength(EnvPath);
1061 SetArrayLength(EnvPath,i+1);
1063 // List \cmd before \bin so \cmd has higher priority and programs in
1064 // there will be called in favor of those in \bin.
1065 EnvPath[i]:=AppDir+'\cmd
';
1067 if RdbPath[GP_CmdTools].Checked then begin
1068 SetArrayLength(EnvPath,i+2);
1069 EnvPath[i+1]:=AppDir+'\bin
';
1073 // Set the current user's PATH directories
.
1074 if not SetEnvStrings('PATH',EnvPath
,True,IsAdminLoggedOn
,True) then begin
1075 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1077 // This
is not a critical error
, so just notify the user
and continue
.
1078 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1083 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1086 GetWindowsVersionEx(Version
);
1087 if Version
.Major
<6 then begin
1088 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1089 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1091 Cmd
:=AppDir
+'\bin\sh.exe';
1092 TempName
:='--login -i';
1094 FileName
:=AppDir
+'\etc\git.ico';
1096 if IsComponentSelected('icons\quicklaunch') then begin
1098 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1102 , '%HOMEDRIVE%%HOMEPATH%'
1109 if IsComponentSelected('icons\desktop') then begin
1111 GetShellFolder('desktop')+'\Git Bash.lnk'
1115 , '%HOMEDRIVE%%HOMEPATH%'
1123 Create the Windows Explorer integrations
1126 if IsAdminLoggedOn
then begin
1127 RootKey
:=HKEY_LOCAL_MACHINE
;
1129 RootKey
:=HKEY_CURRENT_USER
;
1132 if IsComponentSelected('ext\reg\shellhere') then begin
1133 Msg
:='Git Ba&sh Here';
1134 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1135 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1136 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1137 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1138 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1139 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then
1141 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1143 // This
is not a critical error
, so just notify the user
and continue
.
1144 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1149 if IsComponentSelected('ext\reg\guihere') then begin
1150 Msg
:='Git &GUI Here';
1151 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1152 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1153 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1154 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1155 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1156 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
))
1158 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1160 // This
is not a critical error
, so just notify the user
and continue
.
1161 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1166 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1167 if IsComponentSelected('ext\cheetah') then begin
1168 DeleteContextMenuEntries
;
1170 if isWin64
then begin
1171 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1173 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1175 if not ReplaceInUseFile(FileName
,FileName
+'.new',True,Msg
) then begin
1176 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
1177 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
1178 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1179 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1184 Restart any processes that were shut down via the Restart Manager
1187 if SessionHandle
>0 then try
1188 RmRestart(SessionHandle
,0,0);
1189 RmEndSession(SessionHandle
);
1191 Log('Line {#__LINE__}: RmRestart not supported.');
1195 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1199 // Git Path options
.
1201 if RdbPath
[GP_BashOnly
].Checked
then begin
1203 end else if RdbPath
[GP_Cmd
].Checked
then begin
1205 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1208 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1209 if ShouldSaveInf
then begin
1210 SaveInfString('Setup','PathOption',Data
);
1215 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1217 end else if RdbSSH
[GS_Plink
].Checked
then begin
1219 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1220 if ShouldSaveInf
then begin
1221 SaveInfString('Setup','PlinkPath',EdtPlink
.Text);
1224 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1225 if ShouldSaveInf
then begin
1226 SaveInfString('Setup','SSHOption',Data
);
1229 // Line ending conversion options
.
1231 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1233 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1235 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1236 Data
:='CRLFCommitAsIs';
1238 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1239 if ShouldSaveInf
then begin
1240 SaveInfString('Setup','CRLFOption',Data
);
1245 Uninstall event functions
1248 function InitializeUninstall
:Boolean;
1252 ExitButton
,RefreshButton
:TButton
;
1256 Form
:=CreateCustomForm
;
1258 Form
.Caption
:='Git Uninstall: Removing in-use files';
1259 Form
.ClientWidth
:=ScaleX(500);
1260 Form
.ClientHeight
:=ScaleY(256);
1263 Info
:=TLabel
.Create(Form
);
1269 Caption
:='The following applications use files that need to be removed, please close them.';
1272 ContinueButton
:=TButton
.Create(Form
);
1273 with ContinueButton
do begin
1275 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1276 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1279 Caption
:='Continue';
1283 ExitButton
:=TButton
.Create(Form
);
1284 with ExitButton
do begin
1286 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1287 Top
:=ContinueButton
.Top
;
1291 ModalResult
:=mrCancel
;
1295 RefreshButton
:=TButton
.Create(Form
);
1296 with RefreshButton
do begin
1299 Top
:=ExitButton
.Top
;
1303 OnClick
:=@RefreshProcessList
;
1306 ProcessesListBox
:=TListBox
.Create(Form
);
1307 with ProcessesListBox
do begin
1310 Top
:=Info
.Top
+Info
.Height
+11;
1311 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1312 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1315 Form
.ActiveControl
:=ContinueButton
;
1317 RefreshProcessList(NIL);
1318 if GetArrayLength(Processes
)>0 then begin
1319 // Now that these dialogs are going
to be shown
, we should probably
1320 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1321 // unfortunately that
is not possible
with Inno Setup currently
.
1322 Result
:=(Form
.ShowModal()=mrOk
);
1324 // Note
: The number
of processes might have changed during a refresh
.
1325 if Result
and (GetArrayLength(Processes
)>0) then begin
1326 Result
:=(SuppressibleMsgBox(
1327 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1328 'Are you sure you want to continue anyway?'
1342 // Even though the name
of this
function suggests otherwise most
of the
1343 // code below
is only executed right before the actual uninstallation
.
1344 // This happens because
of the
if-guard right
in the beginning
of this
1346 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1348 AppDir
,FileName
,Msg
:String;
1349 EnvPath
:TArrayOfString
;
1352 if CurUninstallStep
<>usUninstall
then begin
1356 // Reset the console
font (the FontType
is reset
in the Registry section
).
1357 if IsComponentInstalled('consolefont') then begin
1358 if SuppressibleMsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
,IDYES
)=IDYES
then begin
1359 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1360 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1361 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1366 Modify the environment
1368 This must happen no later than usUninstall to make
1369 "ChangesEnvironment=yes" not happend before the change!
1372 AppDir
:=ExpandConstant('{app}');
1373 FileName
:=AppDir
+'\setup.ini';
1375 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1376 DeleteMarkedEnvString('GIT_SSH
');
1377 DeleteMarkedEnvString('SVN_SSH
');
1379 // Get the current user's directories
in PATH
.
1380 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1382 // Remove the installation directory from PATH
in any
case, even
if it
1383 // was
not added by the installer
.
1384 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1385 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1390 // Reset the current user
's directories in PATH.
1391 if not SetEnvStrings('PATH
',EnvPath,True,IsAdminLoggedOn,True) then begin
1392 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1394 // This is not a critical error, so just notify the user and continue.
1395 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1399 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
1400 Msg:='Line
{#__LINE__}: Unable
to delete
file "'+FileName+'".';
1402 // This is not a critical error, so just notify the user and continue.
1403 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1408 Delete the Windows Explorer integrations
1411 DeleteContextMenuEntries;
1413 if isWin64 then begin
1414 FileName:=AppDir+'\git
-cheetah\git_shell_ext64
.dll
';
1416 FileName:=AppDir+'\git
-cheetah\git_shell_ext
.dll
';
1418 if FileExists(FileName) then begin
1419 if not UnregisterServer(Is64BitInstallMode,FileName,False) then begin
1420 Msg:='Line
{#__LINE__}: Unable
to unregister
file "'+FileName+'". Please
do it manually by running
"regsvr32 /u '+ExtractFileName(FileName)+'".';
1422 // This is not a critical error, so just notify the user and continue.
1423 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1427 if not DeleteFile(FileName) then begin
1428 Msg:='Line
{#__LINE__}: Unable
to delete
file "'+FileName+'". Please
do it manually after logging off
and on again
.';
1430 // This is not a critical error, so just notify the user and continue.
1431 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);