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
36 DefaultDirName
={pf}\
{#APP_NAME}
38 DefaultGroupName
={#APP_NAME}
39 DisableProgramGroupPage
=auto
41 InfoBeforeFile
=gpl
-2.0.rtf
42 PrivilegesRequired
=none
43 UninstallDisplayIcon
={app}\etc\git
.ico
44 #ifndef COMPILE_FROM_IDE
45 #
if Pos('-',APP_VERSION
)>0
46 VersionInfoVersion
={#Copy(APP_VERSION,1,Pos('-',APP_VERSION)-1)}
48 VersionInfoVersion
={#APP_VERSION}
53 SetupIconFile
=etc\git
.ico
54 WizardImageBackColor
=clWhite
56 WizardImageFile
=git
.bmp
57 WizardSmallImageFile
=gitsmall
.bmp
60 ; Define a custom type to avoid getting the three default types.
61 Name
: default
; Description
: Default installation
; Flags
: iscustom
64 Name
: icons
; Description
: Additional icons
65 Name
: icons\quicklaunch
; Description
: In the Quick Launch
66 Name
: icons\desktop
; Description
: On the Desktop
67 Name
: ext
; Description
: Windows Explorer integration
; Types
: default
68 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: default
69 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: default
70 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: default
71 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: default
72 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: default
73 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: default
74 Name
: consolefont
; Description
: Use a TrueType font
in all console
windows (not only
for Git Bash
)
77 ; Install files that might be in use during setup under a different name.
78 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
79 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
81 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
82 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion; AfterInstall
: DeleteFromVirtualStore
85 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
86 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
87 Name
: {group}\Git Bash
; Filename
: {app}\bin\sh
.exe
; Parameters
: "--login -i"; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; MinVersion
: 6.0
90 BeveledLabel
={#APP_URL}
91 SetupAppTitle
={#APP_NAME} Setup
92 SetupWindowTitle
={#APP_NAME} Setup
95 ; There is no "Console" key in HKLM.
96 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
97 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
98 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
99 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
101 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
102 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
103 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
104 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
106 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
107 ; is a member of the local Administrators group or not (see the "Check" argument).
109 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
110 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
111 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
112 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
113 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
114 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
115 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
117 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
118 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
119 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
120 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
121 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
122 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
124 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
125 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
126 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
127 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
128 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
129 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
131 ; Associate .sh extension with sh.exe so those files are double-clickable,
132 ; startable from cmd.exe, and when files are dropped on them they are passed
133 ; as arguments to the script.
135 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
136 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
137 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
138 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
139 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
140 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
141 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
143 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
144 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
145 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
146 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
147 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
148 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
149 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
152 ; Delete the built-ins.
153 Type: files; Name
: {app}\bin\git
-*.exe
154 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
155 Type: files; Name
: {app}\libexec\git
-core\git
.exe
157 ; Delete any (temporary) git-cheetah files.
158 Type: files; Name
: {app}\git
-cheetah\
*.*
160 ; Delete any manually created shortcuts.
161 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
162 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
163 Type: files; Name
: {app}\Git Bash
.lnk
165 ; Delete a home directory inside the msysGit directory.
166 Type: dirifempty; Name
: {app}\home\
{username}
167 Type: dirifempty; Name
: {app}\home
170 #include
"helpers.inc.iss"
171 #include
"environment.inc.iss"
172 #include
"putty.inc.iss"
173 #include
"modules.inc.iss"
175 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
177 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
179 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
182 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
183 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
195 // Git line ending conversion options
.
198 GC_CRLFCommitAsIs
= 3;
200 // BindImageEx API constants
.
201 BIND_NO_BOUND_IMPORTS
= $00000001;
202 BIND_NO_UPDATE
= $00000002;
203 BIND_ALL_IMAGES
= $00000004;
204 BIND_CACHE_IMPORT_DLLS
= $00000008;
207 // Wizard page
and variables
for the Path options
.
208 PathPage
:TWizardPage
;
209 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
211 // Wizard page
and variables
for the SSH options
.
212 PuTTYPage
:TWizardPage
;
213 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
216 // Wizard page
and variables
for the line ending conversion options
.
217 CRLFPage
:TWizardPage
;
218 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
220 // Wizard page
and variables
for the processes page
.
222 Processes
:ProcessList
;
223 ProcessesPage
:TWizardPage
;
224 ProcessesListBox
:TListBox
;
225 ProcessesRefresh
,ContinueButton
:TButton
;
228 Specific helper functions
231 procedure BrowseForPuTTYFolder(Sender
:TObject
);
236 'Please select a Plink executable'
238 , ExtractFilePath(EdtPlink
.Text)
239 , 'Executable Files|*.exe'
243 if IsPlinkExecutable(Name
) then begin
245 RdbSSH
[GS_Plink
].Checked
:=True;
247 // This
message box only gets triggered on interactive use
, so it
248 // does
not need
to be suppressible
for silent installations
.
249 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
254 procedure DeleteContextMenuEntries
;
256 AppDir
,Command
,Msg
:String;
260 AppDir
:=ExpandConstant('{app}');
262 if IsAdminLoggedOn
then begin
263 RootKey
:=HKEY_LOCAL_MACHINE
;
265 RootKey
:=HKEY_CURRENT_USER
;
268 SetArrayLength(Keys
,4);
269 Keys
[0]:='SOFTWARE\Classes\Directory\shell\git_shell';
270 Keys
[1]:='SOFTWARE\Classes\Directory\Background\shell\git_shell';
271 Keys
[2]:='SOFTWARE\Classes\Directory\shell\git_gui';
272 Keys
[3]:='SOFTWARE\Classes\Directory\Background\shell\git_gui';
274 for i
:=0 to Length(Keys
)-1 do begin
276 RegQueryStringValue(RootKey
,Keys
[i
]+'\command','',Command
);
277 if Pos(AppDir
,Command
)>0 then begin
278 if not RegDeleteKeyIncludingSubkeys(RootKey
,Keys
[i
]) then begin
279 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash / GUI Here" shell extension.';
281 // This
is not a critical error
, so just notify the user
and continue
.
282 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
289 procedure RefreshProcessList(Sender
:TObject
);
291 Version
:TWindowsVersion
;
292 Modules
:TArrayOfString
;
293 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
296 ManualClosingRequired
:Boolean;
298 GetWindowsVersionEx(Version
);
300 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
301 if Version
.Major
>=6 then begin
302 SetArrayLength(Modules
,5);
303 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
304 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
305 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
306 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
307 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
308 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
310 SetArrayLength(Modules
,3);
311 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
312 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
313 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
314 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
316 SetArrayLength(Modules
,2);
317 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
318 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
319 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
321 // Misuse the
"Restartable" flag
to indicate which processes are required
322 // to be closed before setup can continue
, and which just should be closed
323 // in order
to make changes take effect immediately
.
324 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
325 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
326 Processes
[i
]:=ProcsCloseRequired
[i
];
327 Processes
[i
].Restartable
:=False;
329 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
330 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
331 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
335 ManualClosingRequired
:=False;
337 ProcessesListBox
.Items
.Clear
;
338 if (Sender
=NIL) or (SessionHandle
>0) then begin
339 for i
:=0 to GetArrayLength(Processes
)-1 do begin
340 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
341 if Processes
[i
].Restartable
then begin
342 Caption
:=Caption
+', closing is optional';
344 Caption
:=Caption
+', closing is required';
345 ManualClosingRequired
:=True;
347 Caption
:=Caption
+')';
348 ProcessesListBox
.Items
.Append(Caption
);
352 if ContinueButton
<>NIL then begin
353 ContinueButton
.Enabled
:=not ManualClosingRequired
;
357 procedure SetAndMarkEnvString(Name
,Value
:String;Expandable
:Boolean);
362 SetArrayLength(Env
,1);
365 // Try to set the variable
as specified by the user
.
366 if not SetEnvStrings(Name
,Env
,Expandable
,IsAdminLoggedOn
,True) then begin
367 Msg
:='Line {#__LINE__}: Unable to set the '+Name
+' environment variable.';
369 // This
is not a critical error
, so just notify the user
and continue
.
370 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
373 // Mark that we have changed the variable by writing its value
to a
file.
374 FileName
:=ExpandConstant('{app}')+'\setup.ini';
375 if not SetIniString('Environment',Name
,Value
,FileName
) then begin
376 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
378 // This
is not a critical error
, so just notify the user
and continue
.
379 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
385 procedure DeleteMarkedEnvString(Name
:String);
390 Env
:=GetEnvStrings(Name
,IsAdminLoggedOn
);
391 FileName
:=ExpandConstant('{app}')+'\setup.ini';
393 if (GetArrayLength(Env
)=1) and
394 (CompareStr(RemoveQuotes(Env
[0]),GetIniString('Environment',Name
,'',FileName
))=0) then begin
395 if not SetEnvStrings(Name
,[],False,IsAdminLoggedOn
,True) then begin
396 Msg
:='Line {#__LINE__}: Unable to delete the '+Name
+' environment variable.';
398 // This
is not a critical error
, so just notify the user
and continue
.
399 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
406 Setup event functions
409 function InitializeSetup
:Boolean;
415 procedure InitializeWizard
;
418 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
419 LblOpenSSH
,LblPlink
:TLabel
;
420 PuTTYSessions
,EnvSSH
:TArrayOfString
;
421 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
426 PrevPageID
:=wpSelectProgramGroup
;
429 * Create a custom page for modifying the environment.
432 PathPage
:=CreateCustomPage(
434 , 'Adjusting your PATH environment'
435 , 'How would you like to use Git from the command line?'
437 PrevPageID
:=PathPage
.ID
;
440 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
441 with RdbPath
[GP_BashOnly
] do begin
442 Parent
:=PathPage
.Surface
;
443 Caption
:='Use Git from Git Bash only';
448 Font
.Style
:=[fsBold
];
452 LblGitBash
:=TLabel
.Create(PathPage
);
453 with LblGitBash
do begin
454 Parent
:=PathPage
.Surface
;
456 'This is the safest choice as your PATH will not be modified at all. You will only be' + #
13 +
457 'able to use the Git command line tools from Git Bash.';
465 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
466 with RdbPath
[GP_Cmd
] do begin
467 Parent
:=PathPage
.Surface
;
468 Caption
:='Use Git from the Windows Command Prompt';
473 Font
.Style
:=[fsBold
];
476 LblGitCmd
:=TLabel
.Create(PathPage
);
477 with LblGitCmd
do begin
478 Parent
:=PathPage
.Surface
;
480 'This option is considered safe as it only adds some minimal Git wrappers to your' + #
13 +
481 'PATH to avoid cluttering your environment with optional Unix tools. You will be' + #
13 +
482 'able to use Git from both Git Bash and the Windows Command Prompt.';
490 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
491 with RdbPath
[GP_CmdTools
] do begin
492 Parent
:=PathPage
.Surface
;
493 Caption
:='Use Git and optional Unix tools from the Windows Command Prompt';
498 Font
.Style
:=[fsBold
];
501 LblGitCmdTools
:=TLabel
.Create(PathPage
);
502 with LblGitCmdTools
do begin
503 Parent
:=PathPage
.Surface
;
504 Caption
:='Both Git and the optional Unix tools will be added to your PATH.';
510 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
511 with LblGitCmdToolsWarn
do begin
512 Parent
:=PathPage
.Surface
;
514 'Warning: This will override Windows tools like "find" and "sort". Only' + #
13 +
515 'use this option if you understand the implications.';
521 Font
.Style
:=[fsBold
];
524 // Restore the setting chosen during a previous install
.
525 Data
:=GetPreviousData('Path Option','BashOnly');
527 // Use settings from the user provided INF
.
528 if ShouldLoadInf
then begin
529 Data
:=LoadInfString('Setup','PathOption','BashOnly');
532 if Data
='BashOnly' then begin
533 RdbPath
[GP_BashOnly
].Checked
:=True;
534 end else if Data
='Cmd' then begin
535 RdbPath
[GP_Cmd
].Checked
:=True;
536 end else if Data
='CmdTools' then begin
537 RdbPath
[GP_CmdTools
].Checked
:=True;
541 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
542 * if at least one PuTTY session is found in the Registry.
545 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
546 PuTTYPage
:=CreateCustomPage(
548 , 'Choosing the SSH executable'
549 , 'Which Secure Shell client program would you like Git to use?'
551 PrevPageID
:=PuTTYPage
.ID
;
554 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
555 with RdbSSH
[GS_OpenSSH
] do begin
556 Parent
:=PuTTYPage
.Surface
;
557 Caption
:='Use OpenSSH';
562 Font
.Style
:=[fsBold
];
566 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
567 with LblOpenSSH
do begin
568 Parent
:=PuTTYPage
.Surface
;
570 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
571 'environment variables will not be modified.';
579 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
580 with RdbSSH
[GS_Plink
] do begin
581 Parent
:=PuTTYPage
.Surface
;
582 Caption
:='Use (Tortoise)Plink';
587 Font
.Style
:=[fsBold
];
590 LblPlink
:=TLabel
.Create(PuTTYPage
);
591 with LblPlink
do begin
592 Parent
:=PuTTYPage
.Surface
;
594 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
595 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
596 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
597 'variables will be adjusted to point to the following executable:';
603 EdtPlink
:=TEdit
.Create(PuTTYPage
);
604 with EdtPlink
do begin
605 Parent
:=PuTTYPage
.Surface
;
607 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
608 if (GetArrayLength(EnvSSH
)=1) and IsPlinkExecutable(EnvSSH
[0]) then begin
611 if not FileExists(Text) then begin
612 Text:=GetPreviousData('Plink Path','');
614 if not FileExists(Text) then begin
615 Text:=GuessPlinkExecutable
;
617 if not FileExists(Text) then begin
626 BtnPlink
:=TButton
.Create(PuTTYPage
);
627 with BtnPlink
do begin
628 Parent
:=PuTTYPage
.Surface
;
630 OnClick
:=@BrowseForPuTTYFolder
;
637 // Restore the setting chosen during a previous install
.
638 Data
:=GetPreviousData('SSH Option','OpenSSH');
640 // Use settings from the user provided INF
.
641 if ShouldLoadInf
then begin
642 Data
:=LoadInfString('Setup','SSHOption','OpenSSH');
645 if Data
='OpenSSH' then begin
646 RdbSSH
[GS_OpenSSH
].Checked
:=True;
647 end else if Data
='Plink' then begin
648 RdbSSH
[GS_Plink
].Checked
:=True;
655 * Create a custom page for the core.autocrlf setting.
658 CRLFPage
:=CreateCustomPage(
660 , 'Configuring the line ending conversions'
661 , 'How should Git treat line endings in text files?'
663 PrevPageID
:=CRLFPage
.ID
;
666 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
667 with RdbCRLF
[GC_CRLFAlways
] do begin
668 Parent
:=CRLFPage
.Surface
;
669 Caption
:='Checkout Windows-style, commit Unix-style line endings';
674 Font
.Style
:=[fsBold
];
678 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
679 with LblCRLFAlways
do begin
680 Parent
:=CRLFPage
.Surface
;
682 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
683 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
684 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
692 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
693 with RdbCRLF
[GC_LFOnly
] do begin
694 Parent
:=CRLFPage
.Surface
;
695 Caption
:='Checkout as-is, commit Unix-style line endings';
700 Font
.Style
:=[fsBold
];
704 LblLFOnly
:=TLabel
.Create(CRLFPage
);
705 with LblLFOnly
do begin
706 Parent
:=CRLFPage
.Surface
;
708 'Git will not perform any conversion when checking out text files. When' + #
13 +
709 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
710 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
718 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
719 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
720 Parent
:=CRLFPage
.Surface
;
721 Caption
:='Checkout as-is, commit as-is';
726 Font
.Style
:=[fsBold
];
730 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
731 with LblCRLFCommitAsIs
do begin
732 Parent
:=CRLFPage
.Surface
;
734 'Git will not perform any conversions when checking out or committing' + #
13 +
735 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
736 'projects ("core.autocrlf" is set to "false").';
743 // Restore the setting chosen during a previous install
.
744 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
746 // Use settings from the user provided INF
.
747 if ShouldLoadInf
then begin
748 Data
:=LoadInfString('Setup','CRLFOption','CRLFAlways');
751 if Data
='LFOnly' then begin
752 RdbCRLF
[GC_LFOnly
].Checked
:=True;
753 end else if Data
='CRLFAlways' then begin
754 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
755 end else if Data
='CRLFCommitAsIs' then begin
756 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
760 * Create a custom page for finding the processes that lock a module.
763 ProcessesPage
:=CreateCustomPage(
765 , 'Replacing in-use files'
766 , 'The following applications use files that need to be replaced, please close them.'
769 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
770 with ProcessesListBox
do begin
771 Parent
:=ProcessesPage
.Surface
;
772 Width
:=ProcessesPage
.SurfaceWidth
;
773 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
776 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
777 with ProcessesRefresh
do begin
779 Width
:=WizardForm
.CancelButton
.Width
;
780 Height
:=WizardForm
.CancelButton
.Height
;
781 Top
:=WizardForm
.CancelButton
.Top
;
782 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
784 OnClick
:=@RefreshProcessList
;
787 // This button
is only used by the uninstaller
.
790 // Initially hide the Refresh button
, show it when the process page becomes current
.
791 ProcessesRefresh
.Hide
;
794 function ShouldSkipPage(PageID
:Integer):Boolean;
796 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
797 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
798 RefreshProcessList(NIL);
799 Result
:=(GetArrayLength(Processes
)=0);
805 procedure CurPageChanged(CurPageID
:Integer);
807 if CurPageID
=wpInfoBefore
then begin
808 if WizardForm
.NextButton
.Enabled
then begin
809 // By default
, do not show a blinking cursor
for InfoBeforeFile
.
810 WizardForm
.ActiveControl
:=WizardForm
.NextButton
;
812 end else if CurPageID
=wpSelectDir
then begin
813 if not IsDirWritable(WizardDirValue
) then begin
814 // If the default directory
is not writable
, choose another default that most likely
is.
815 // This will be checked later again when the user clicks
"Next".
816 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
818 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
819 // Show the
"Refresh" button only on the processes page
.
820 ProcessesRefresh
.Show
;
822 ProcessesRefresh
.Hide
;
826 function NextButtonClick(CurPageID
:Integer):Boolean;
829 Version
:TWindowsVersion
;
831 // On a silent install
, if your NextButtonClick
function returns
False
832 // prior
to installation starting
, Setup will exit automatically
.
835 if CurPageID
=wpSelectDir
then begin
836 if not IsDirWritable(WizardDirValue
) then begin
838 'The specified installation directory does not seem to be writable. ' +
839 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
849 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
850 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
851 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
852 if not Result
then begin
853 SuppressibleMsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
,IDOK
);
855 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
856 // It would have been nicer
to just disable the
"Next" button
, but the
857 // WizardForm
exports the button just
read-only
.
858 for i
:=0 to GetArrayLength(Processes
)-1 do begin
859 if not Processes
[i
].Restartable
then begin
861 'Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".'
871 Result
:=(GetArrayLength(Processes
)=0);
873 if not Result
then begin
874 GetWindowsVersionEx(Version
);
875 if Version
.Major
>=6 then begin
876 Result
:=(SuppressibleMsgBox(
877 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
878 'Are you sure you want to continue?'
884 Result
:=(SuppressibleMsgBox(
885 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
886 'Are you sure you want to continue anyway?'
896 procedure CurStepChanged(CurStep
:TSetupStep
);
898 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
899 BuiltIns
,ImageNames
,EnvPath
,EnvHome
:TArrayOfString
;
904 Version
:TWindowsVersion
;
906 if CurStep
=ssInstall
then begin
907 // Shutdown locking processes just before the actual installation starts
.
908 if SessionHandle
>0 then try
909 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
911 Log('Line {#__LINE__}: RmShutdown not supported.');
917 // Make sure the code below
is only executed just after the actual installation finishes
.
918 if CurStep
<>ssPostInstall
then begin
922 AppDir
:=ExpandConstant('{app}');
925 Bind the imported function addresses
929 DllPath
:=ExpandConstant('{app}\bin;{sys}');
931 // Load the list
of images from a
text file.
932 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
933 if LoadStringsFromFile(FileName
,ImageNames
) then begin
934 Count
:=GetArrayLength(ImageNames
)-1;
935 for i
:=0 to Count
do begin
936 FileName
:=AppDir
+'\'+ImageNames[i];
937 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
938 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
943 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
950 // Load the built-ins from a text file.
951 FileName:=AppDir+'\
{#APP_BUILTINS}';
952 if LoadStringsFromFile(FileName,BuiltIns) then begin
953 Count:=GetArrayLength(BuiltIns)-1;
955 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
956 for i:=0 to Count do begin
957 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
958 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
959 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
963 // Create built
-ins
as aliases
for git
.exe
.
964 for i
:=0 to Count
do begin
965 FileName
:=AppDir
+'\'+BuiltIns[i];
967 // Delete any existing built-in.
968 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
969 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
974 // This will throw an exception on pre-Win2k systems.
975 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
978 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
981 if not LinkCreated then begin
982 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
983 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
984 // This is not a critical error, Git could basically be used without the
985 // aliases for built-ins, so we continue.
990 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
991 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
993 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
994 FileName:=AppDir+'\bin
\'+FindRec
.name
;
995 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
996 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
999 until not FindNext(FindRec
);
1003 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
1005 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
1006 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
1007 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1015 if RdbCRLF
[GC_LFOnly
].checked
then begin
1016 Cmd
:='core.autocrlf input';
1017 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
1018 Cmd
:='core.autocrlf true';
1020 Cmd
:='core.autocrlf false';
1022 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
1023 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
1024 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
1026 // This
is not a critical error
, so just notify the user
and continue
.
1027 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1032 Modify the environment
1034 This must happen no later than ssPostInstall to make
1035 "ChangesEnvironment=yes" not happend before the change!
1038 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
1039 DeleteMarkedEnvString('GIT_SSH');
1040 DeleteMarkedEnvString('SVN_SSH');
1042 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
1043 SetAndMarkEnvString('GIT_SSH',EdtPlink
.Text,True);
1044 SetAndMarkEnvString('SVN_SSH',EdtPlink
.Text,True);
1047 // Get the current user
's directories in PATH.
1048 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1050 // First, remove the installation directory from PATH in any case.
1051 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1052 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1057 // Modify the PATH variable as requested by the user.
1058 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1059 i:=GetArrayLength(EnvPath);
1060 SetArrayLength(EnvPath,i+1);
1062 // List \cmd before \bin so \cmd has higher priority and programs in
1063 // there will be called in favor of those in \bin.
1064 EnvPath[i]:=AppDir+'\cmd
';
1066 if RdbPath[GP_CmdTools].Checked then begin
1067 SetArrayLength(EnvPath,i+2);
1068 EnvPath[i+1]:=AppDir+'\bin
';
1072 // Set the current user's PATH directories
.
1073 if not SetEnvStrings('PATH',EnvPath
,True,IsAdminLoggedOn
,True) then begin
1074 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1076 // This
is not a critical error
, so just notify the user
and continue
.
1077 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1082 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1085 GetWindowsVersionEx(Version
);
1086 if Version
.Major
<6 then begin
1087 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1088 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1090 Cmd
:=AppDir
+'\bin\sh.exe';
1091 TempName
:='--login -i';
1093 FileName
:=AppDir
+'\etc\git.ico';
1095 if IsComponentSelected('icons\quicklaunch') then begin
1097 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1101 , '%HOMEDRIVE%%HOMEPATH%'
1108 if IsComponentSelected('icons\desktop') then begin
1110 GetShellFolder('desktop')+'\Git Bash.lnk'
1114 , '%HOMEDRIVE%%HOMEPATH%'
1122 Create the Windows Explorer integrations
1125 if IsAdminLoggedOn
then begin
1126 RootKey
:=HKEY_LOCAL_MACHINE
;
1128 RootKey
:=HKEY_CURRENT_USER
;
1131 if IsComponentSelected('ext\reg\shellhere') then begin
1132 Msg
:='Git Ba&sh Here';
1133 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1134 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1135 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1136 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1137 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1138 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then
1140 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1142 // This
is not a critical error
, so just notify the user
and continue
.
1143 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1148 if IsComponentSelected('ext\reg\guihere') then begin
1149 Msg
:='Git &GUI Here';
1150 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1151 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1152 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1153 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1154 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1155 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
))
1157 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1159 // This
is not a critical error
, so just notify the user
and continue
.
1160 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1165 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1166 if IsComponentSelected('ext\cheetah') then begin
1167 DeleteContextMenuEntries
;
1169 if isWin64
then begin
1170 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1172 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1174 if not ReplaceInUseFile(FileName
,FileName
+'.new',True,Msg
) then begin
1175 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
1176 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
1177 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1178 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1183 Restart any processes that were shut down via the Restart Manager
1186 if SessionHandle
>0 then try
1187 RmRestart(SessionHandle
,0,0);
1188 RmEndSession(SessionHandle
);
1190 Log('Line {#__LINE__}: RmRestart not supported.');
1194 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1198 // Git Path options
.
1200 if RdbPath
[GP_BashOnly
].Checked
then begin
1202 end else if RdbPath
[GP_Cmd
].Checked
then begin
1204 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1207 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1208 if ShouldSaveInf
then begin
1209 SaveInfString('Setup','PathOption',Data
);
1214 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1216 end else if RdbSSH
[GS_Plink
].Checked
then begin
1218 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1219 if ShouldSaveInf
then begin
1220 SaveInfString('Setup','PlinkPath',EdtPlink
.Text);
1223 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1224 if ShouldSaveInf
then begin
1225 SaveInfString('Setup','SSHOption',Data
);
1228 // Line ending conversion options
.
1230 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1232 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1234 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1235 Data
:='CRLFCommitAsIs';
1237 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1238 if ShouldSaveInf
then begin
1239 SaveInfString('Setup','CRLFOption',Data
);
1244 Uninstall event functions
1247 function InitializeUninstall
:Boolean;
1251 ExitButton
,RefreshButton
:TButton
;
1255 Form
:=CreateCustomForm
;
1257 Form
.Caption
:='Git Uninstall: Removing in-use files';
1258 Form
.ClientWidth
:=ScaleX(500);
1259 Form
.ClientHeight
:=ScaleY(256);
1262 Info
:=TLabel
.Create(Form
);
1268 Caption
:='The following applications use files that need to be removed, please close them.';
1271 ContinueButton
:=TButton
.Create(Form
);
1272 with ContinueButton
do begin
1274 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1275 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1278 Caption
:='Continue';
1282 ExitButton
:=TButton
.Create(Form
);
1283 with ExitButton
do begin
1285 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1286 Top
:=ContinueButton
.Top
;
1290 ModalResult
:=mrCancel
;
1294 RefreshButton
:=TButton
.Create(Form
);
1295 with RefreshButton
do begin
1298 Top
:=ExitButton
.Top
;
1302 OnClick
:=@RefreshProcessList
;
1305 ProcessesListBox
:=TListBox
.Create(Form
);
1306 with ProcessesListBox
do begin
1309 Top
:=Info
.Top
+Info
.Height
+11;
1310 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1311 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1314 Form
.ActiveControl
:=ContinueButton
;
1316 RefreshProcessList(NIL);
1317 if GetArrayLength(Processes
)>0 then begin
1318 // Now that these dialogs are going
to be shown
, we should probably
1319 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1320 // unfortunately that
is not possible
with Inno Setup currently
.
1321 Result
:=(Form
.ShowModal()=mrOk
);
1323 // Note
: The number
of processes might have changed during a refresh
.
1324 if Result
and (GetArrayLength(Processes
)>0) then begin
1325 Result
:=(SuppressibleMsgBox(
1326 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1327 'Are you sure you want to continue anyway?'
1341 // Even though the name
of this
function suggests otherwise most
of the
1342 // code below
is only executed right before the actual uninstallation
.
1343 // This happens because
of the
if-guard right
in the beginning
of this
1345 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1347 AppDir
,FileName
,Msg
:String;
1348 EnvPath
:TArrayOfString
;
1351 if CurUninstallStep
<>usUninstall
then begin
1355 // Reset the console
font (the FontType
is reset
in the Registry section
).
1356 if IsComponentInstalled('consolefont') then begin
1357 if SuppressibleMsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
,IDYES
)=IDYES
then begin
1358 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1359 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1360 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1365 Modify the environment
1367 This must happen no later than usUninstall to make
1368 "ChangesEnvironment=yes" not happend before the change!
1371 AppDir
:=ExpandConstant('{app}');
1372 FileName
:=AppDir
+'\setup.ini';
1374 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1375 DeleteMarkedEnvString('GIT_SSH
');
1376 DeleteMarkedEnvString('SVN_SSH
');
1378 // Get the current user's directories
in PATH
.
1379 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1381 // Remove the installation directory from PATH
in any
case, even
if it
1382 // was
not added by the installer
.
1383 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1384 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1389 // Reset the current user
's directories in PATH.
1390 if not SetEnvStrings('PATH
',EnvPath,True,IsAdminLoggedOn,True) then begin
1391 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1393 // This is not a critical error, so just notify the user and continue.
1394 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1398 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
1399 Msg:='Line
{#__LINE__}: Unable
to delete
file "'+FileName+'".';
1401 // This is not a critical error, so just notify the user and continue.
1402 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1407 Delete the Windows Explorer integrations
1410 DeleteContextMenuEntries;
1412 if isWin64 then begin
1413 FileName:=AppDir+'\git
-cheetah\git_shell_ext64
.dll
';
1415 FileName:=AppDir+'\git
-cheetah\git_shell_ext
.dll
';
1417 if FileExists(FileName) then begin
1418 if not UnregisterServer(Is64BitInstallMode,FileName,False) then begin
1419 Msg:='Line
{#__LINE__}: Unable
to unregister
file "'+FileName+'". Please
do it manually by running
"regsvr32 /u '+ExtractFileName(FileName)+'".';
1421 // This is not a critical error, so just notify the user and continue.
1422 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
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
.';
1429 // This is not a critical error, so just notify the user and continue.
1430 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);