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.googlecode.com/'
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 procedure InitializeWizard
;
412 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
413 LblOpenSSH
,LblPlink
:TLabel
;
414 PuTTYSessions
,EnvSSH
:TArrayOfString
;
415 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
420 PrevPageID
:=wpSelectProgramGroup
;
423 * Create a custom page for modifying the environment.
426 PathPage
:=CreateCustomPage(
428 , 'Adjusting your PATH environment'
429 , 'How would you like to use Git from the command line?'
431 PrevPageID
:=PathPage
.ID
;
434 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
435 with RdbPath
[GP_BashOnly
] do begin
436 Parent
:=PathPage
.Surface
;
437 Caption
:='Use Git Bash only';
442 Font
.Style
:=[fsBold
];
446 LblGitBash
:=TLabel
.Create(PathPage
);
447 with LblGitBash
do begin
448 Parent
:=PathPage
.Surface
;
450 'This is the most conservative choice if you are concerned about the stability' + #
13 +
451 'of your system. Your PATH will not be modified.';
459 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
460 with RdbPath
[GP_Cmd
] do begin
461 Parent
:=PathPage
.Surface
;
462 Caption
:='Run Git from the Windows Command Prompt';
467 Font
.Style
:=[fsBold
];
470 LblGitCmd
:=TLabel
.Create(PathPage
);
471 with LblGitCmd
do begin
472 Parent
:=PathPage
.Surface
;
474 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
475 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
476 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
484 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
485 with RdbPath
[GP_CmdTools
] do begin
486 Parent
:=PathPage
.Surface
;
487 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
492 Font
.Style
:=[fsBold
];
495 LblGitCmdTools
:=TLabel
.Create(PathPage
);
496 with LblGitCmdTools
do begin
497 Parent
:=PathPage
.Surface
;
498 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
504 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
505 with LblGitCmdToolsWarn
do begin
506 Parent
:=PathPage
.Surface
;
508 'Warning: This will override Windows tools like find.exe and' + #
13 +
509 'sort.exe. Select this option only if you understand the implications.';
515 Font
.Style
:=[fsBold
];
518 // Restore the setting chosen during a previous install
.
519 Data
:=GetPreviousData('Path Option','BashOnly');
520 if Data
='BashOnly' then begin
521 RdbPath
[GP_BashOnly
].Checked
:=True;
522 end else if Data
='Cmd' then begin
523 RdbPath
[GP_Cmd
].Checked
:=True;
524 end else if Data
='CmdTools' then begin
525 RdbPath
[GP_CmdTools
].Checked
:=True;
529 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
530 * if at least one PuTTY session is found in the Registry.
533 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
534 PuTTYPage
:=CreateCustomPage(
536 , 'Choosing the SSH executable'
537 , 'Which Secure Shell client program would you like Git to use?'
539 PrevPageID
:=PuTTYPage
.ID
;
542 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
543 with RdbSSH
[GS_OpenSSH
] do begin
544 Parent
:=PuTTYPage
.Surface
;
545 Caption
:='Use OpenSSH';
550 Font
.Style
:=[fsBold
];
554 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
555 with LblOpenSSH
do begin
556 Parent
:=PuTTYPage
.Surface
;
558 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
559 'environment variables will not be modified.';
567 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
568 with RdbSSH
[GS_Plink
] do begin
569 Parent
:=PuTTYPage
.Surface
;
570 Caption
:='Use (Tortoise)Plink';
575 Font
.Style
:=[fsBold
];
578 LblPlink
:=TLabel
.Create(PuTTYPage
);
579 with LblPlink
do begin
580 Parent
:=PuTTYPage
.Surface
;
582 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
583 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
584 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
585 'variables will be adjusted to point to the following executable:';
591 EdtPlink
:=TEdit
.Create(PuTTYPage
);
592 with EdtPlink
do begin
593 Parent
:=PuTTYPage
.Surface
;
595 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
596 if (GetArrayLength(EnvSSH
)=1) and IsPlinkExecutable(EnvSSH
[0]) then begin
599 if not FileExists(Text) then begin
600 Text:=GetPreviousData('Plink Path','');
602 if not FileExists(Text) then begin
603 Text:=GuessPlinkExecutable
;
605 if not FileExists(Text) then begin
614 BtnPlink
:=TButton
.Create(PuTTYPage
);
615 with BtnPlink
do begin
616 Parent
:=PuTTYPage
.Surface
;
618 OnClick
:=@BrowseForPuTTYFolder
;
625 // Restore the setting chosen during a previous install
.
626 Data
:=GetPreviousData('SSH Option','OpenSSH');
627 if Data
='OpenSSH' then begin
628 RdbSSH
[GS_OpenSSH
].Checked
:=True;
629 end else if Data
='Plink' then begin
630 RdbSSH
[GS_Plink
].Checked
:=True;
637 * Create a custom page for the core.autocrlf setting.
640 CRLFPage
:=CreateCustomPage(
642 , 'Configuring the line ending conversions'
643 , 'How should Git treat line endings in text files?'
645 PrevPageID
:=CRLFPage
.ID
;
648 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
649 with RdbCRLF
[GC_CRLFAlways
] do begin
650 Parent
:=CRLFPage
.Surface
;
651 Caption
:='Checkout Windows-style, commit Unix-style line endings';
656 Font
.Style
:=[fsBold
];
660 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
661 with LblCRLFAlways
do begin
662 Parent
:=CRLFPage
.Surface
;
664 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
665 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
666 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
674 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
675 with RdbCRLF
[GC_LFOnly
] do begin
676 Parent
:=CRLFPage
.Surface
;
677 Caption
:='Checkout as-is, commit Unix-style line endings';
682 Font
.Style
:=[fsBold
];
686 LblLFOnly
:=TLabel
.Create(CRLFPage
);
687 with LblLFOnly
do begin
688 Parent
:=CRLFPage
.Surface
;
690 'Git will not perform any conversion when checking out text files. When' + #
13 +
691 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
692 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
700 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
701 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
702 Parent
:=CRLFPage
.Surface
;
703 Caption
:='Checkout as-is, commit as-is';
708 Font
.Style
:=[fsBold
];
712 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
713 with LblCRLFCommitAsIs
do begin
714 Parent
:=CRLFPage
.Surface
;
716 'Git will not perform any conversions when checking out or committing' + #
13 +
717 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
718 'projects ("core.autocrlf" is set to "false").';
725 // Restore the setting chosen during a previous install
.
726 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
727 if Data
='LFOnly' then begin
728 RdbCRLF
[GC_LFOnly
].Checked
:=True;
729 end else if Data
='CRLFAlways' then begin
730 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
731 end else if Data
='CRLFCommitAsIs' then begin
732 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
736 * Create a custom page for finding the processes that lock a module.
739 ProcessesPage
:=CreateCustomPage(
741 , 'Replacing in-use files'
742 , 'The following applications use files that need to be replaced, please close them.'
745 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
746 with ProcessesListBox
do begin
747 Parent
:=ProcessesPage
.Surface
;
748 Width
:=ProcessesPage
.SurfaceWidth
;
749 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
752 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
753 with ProcessesRefresh
do begin
755 Width
:=WizardForm
.CancelButton
.Width
;
756 Height
:=WizardForm
.CancelButton
.Height
;
757 Top
:=WizardForm
.CancelButton
.Top
;
758 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
760 OnClick
:=@RefreshProcessList
;
763 // This button
is only used by the uninstaller
.
766 // Initially hide the Refresh button
, show it when the process page becomes current
.
767 ProcessesRefresh
.Hide
;
770 function ShouldSkipPage(PageID
:Integer):Boolean;
772 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
773 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
774 RefreshProcessList(NIL);
775 Result
:=(GetArrayLength(Processes
)=0);
781 procedure CurPageChanged(CurPageID
:Integer);
783 if CurPageID
=wpInfoBefore
then begin
784 if WizardForm
.NextButton
.Enabled
then begin
785 // By default
, do not show a blinking cursor
for InfoBeforeFile
.
786 WizardForm
.ActiveControl
:=WizardForm
.NextButton
;
788 end else if CurPageID
=wpSelectDir
then begin
789 if not IsDirWritable(WizardDirValue
) then begin
790 // If the default directory
is not writable
, choose another default that most likely
is.
791 // This will be checked later again when the user clicks
"Next".
792 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
794 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
795 // Show the
"Refresh" button only on the processes page
.
796 ProcessesRefresh
.Show
;
798 ProcessesRefresh
.Hide
;
802 function NextButtonClick(CurPageID
:Integer):Boolean;
805 Version
:TWindowsVersion
;
807 // On a silent install
, if your NextButtonClick
function returns
False
808 // prior
to installation starting
, Setup will exit automatically
.
811 if CurPageID
=wpSelectDir
then begin
812 if not IsDirWritable(WizardDirValue
) then begin
814 'The specified installation directory does not seem to be writable. ' +
815 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
825 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
826 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
827 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
828 if not Result
then begin
829 SuppressibleMsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
,IDOK
);
831 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
832 // It would have been nicer
to just disable the
"Next" button
, but the
833 // WizardForm
exports the button just
read-only
.
834 for i
:=0 to GetArrayLength(Processes
)-1 do begin
835 if not Processes
[i
].Restartable
then begin
837 'Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".'
847 Result
:=(GetArrayLength(Processes
)=0);
849 if not Result
then begin
850 GetWindowsVersionEx(Version
);
851 if Version
.Major
>=6 then begin
852 Result
:=(SuppressibleMsgBox(
853 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
854 'Are you sure you want to continue?'
860 Result
:=(SuppressibleMsgBox(
861 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
862 'Are you sure you want to continue anyway?'
872 procedure CurStepChanged(CurStep
:TSetupStep
);
874 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
875 BuiltIns
,ImageNames
,EnvPath
,EnvHome
:TArrayOfString
;
880 Version
:TWindowsVersion
;
882 if CurStep
=ssInstall
then begin
883 // Shutdown locking processes just before the actual installation starts
.
884 if SessionHandle
>0 then try
885 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
887 Log('Line {#__LINE__}: RmShutdown not supported.');
893 // Make sure the code below
is only executed just after the actual installation finishes
.
894 if CurStep
<>ssPostInstall
then begin
898 AppDir
:=ExpandConstant('{app}');
901 Bind the imported function addresses
905 DllPath
:=ExpandConstant('{app}\bin;{sys}');
907 // Load the list
of images from a
text file.
908 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
909 if LoadStringsFromFile(FileName
,ImageNames
) then begin
910 Count
:=GetArrayLength(ImageNames
)-1;
911 for i
:=0 to Count
do begin
912 FileName
:=AppDir
+'\'+ImageNames[i];
913 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
914 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
919 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
926 // Load the built-ins from a text file.
927 FileName:=AppDir+'\
{#APP_BUILTINS}';
928 if LoadStringsFromFile(FileName,BuiltIns) then begin
929 Count:=GetArrayLength(BuiltIns)-1;
931 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
932 for i:=0 to Count do begin
933 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
934 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
935 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
939 // Create built
-ins
as aliases
for git
.exe
.
940 for i
:=0 to Count
do begin
941 FileName
:=AppDir
+'\'+BuiltIns[i];
943 // Delete any existing built-in.
944 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
945 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
950 // This will throw an exception on pre-Win2k systems.
951 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
954 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
957 if not LinkCreated then begin
958 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
959 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
960 // This is not a critical error, Git could basically be used without the
961 // aliases for built-ins, so we continue.
966 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
967 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
969 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
970 FileName:=AppDir+'\bin
\'+FindRec
.name
;
971 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
972 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
975 until not FindNext(FindRec
);
979 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
981 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
982 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
983 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
991 if RdbCRLF
[GC_LFOnly
].checked
then begin
992 Cmd
:='core.autocrlf input';
993 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
994 Cmd
:='core.autocrlf true';
996 Cmd
:='core.autocrlf false';
998 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
999 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
1000 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
1002 // This
is not a critical error
, so just notify the user
and continue
.
1003 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1008 Modify the environment
1010 This must happen no later than ssPostInstall to make
1011 "ChangesEnvironment=yes" not happend before the change!
1014 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
1015 DeleteMarkedEnvString('GIT_SSH');
1016 DeleteMarkedEnvString('SVN_SSH');
1018 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
1019 SetAndMarkEnvString('GIT_SSH',EdtPlink
.Text,True);
1020 SetAndMarkEnvString('SVN_SSH',EdtPlink
.Text,True);
1023 // Get the current user
's directories in PATH.
1024 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1026 // First, remove the installation directory from PATH in any case.
1027 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1028 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1033 // Delete HOME if a previous installation modified it.
1034 DeleteMarkedEnvString('HOME
');
1036 // Modify the PATH variable as requested by the user.
1037 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1038 i:=GetArrayLength(EnvPath);
1039 SetArrayLength(EnvPath,i+1);
1041 // List \cmd before \bin so \cmd has higher priority and programs in
1042 // there will be called in favor of those in \bin.
1043 EnvPath[i]:=AppDir+'\cmd
';
1045 if RdbPath[GP_CmdTools].Checked then begin
1046 SetArrayLength(EnvPath,i+2);
1047 EnvPath[i+1]:=AppDir+'\bin
';
1049 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1050 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1051 i:=GetArrayLength(EnvHome);
1052 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1053 SetAndMarkEnvString('HOME
','%HOMEDRIVE
%%HOMEPATH
%',True);
1058 // Set the current user's PATH directories
.
1059 if not SetEnvStrings('PATH',EnvPath
,True,IsAdminLoggedOn
,True) then begin
1060 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1062 // This
is not a critical error
, so just notify the user
and continue
.
1063 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1068 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1071 GetWindowsVersionEx(Version
);
1072 if Version
.Major
<6 then begin
1073 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1074 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1076 Cmd
:=AppDir
+'\bin\sh.exe';
1077 TempName
:='--login -i';
1079 FileName
:=AppDir
+'\etc\git.ico';
1081 if IsComponentSelected('icons\quicklaunch') then begin
1083 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1087 , '%HOMEDRIVE%%HOMEPATH%'
1094 if IsComponentSelected('icons\desktop') then begin
1096 GetShellFolder('desktop')+'\Git Bash.lnk'
1100 , '%HOMEDRIVE%%HOMEPATH%'
1108 Create the Windows Explorer integrations
1111 if IsAdminLoggedOn
then begin
1112 RootKey
:=HKEY_LOCAL_MACHINE
;
1114 RootKey
:=HKEY_CURRENT_USER
;
1117 if IsComponentSelected('ext\reg\shellhere') then begin
1118 Msg
:='Git Ba&sh Here';
1119 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1120 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1121 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1122 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1123 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1124 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then
1126 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1128 // This
is not a critical error
, so just notify the user
and continue
.
1129 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1134 if IsComponentSelected('ext\reg\guihere') then begin
1135 Msg
:='Git &GUI Here';
1136 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1137 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1138 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1139 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1140 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1141 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
))
1143 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1145 // This
is not a critical error
, so just notify the user
and continue
.
1146 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1151 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1152 if IsComponentSelected('ext\cheetah') then begin
1153 DeleteContextMenuEntries
;
1155 if isWin64
then begin
1156 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1158 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1160 if not ReplaceInUseFile(FileName
,FileName
+'.new',True,Msg
) then begin
1161 // This
is in fact a critical error
, but
"Abort" does
not work during ssPostInstall anymore
and
1162 // we have no other way
of aborting the installation
, so just notify the user
and continue
.
1163 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1164 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1169 Restart any processes that were shut down via the Restart Manager
1172 if SessionHandle
>0 then try
1173 RmRestart(SessionHandle
,0,0);
1174 RmEndSession(SessionHandle
);
1176 Log('Line {#__LINE__}: RmRestart not supported.');
1180 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1184 // Git Path options
.
1186 if RdbPath
[GP_BashOnly
].Checked
then begin
1188 end else if RdbPath
[GP_Cmd
].Checked
then begin
1190 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1193 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1197 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1199 end else if RdbSSH
[GS_Plink
].Checked
then begin
1201 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1203 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1205 // Line ending conversion options
.
1207 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1209 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1211 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1212 Data
:='CRLFCommitAsIs';
1214 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1218 Uninstall event functions
1221 function InitializeUninstall
:Boolean;
1225 ExitButton
,RefreshButton
:TButton
;
1229 Form
:=CreateCustomForm
;
1231 Form
.Caption
:='Git Uninstall: Removing in-use files';
1232 Form
.ClientWidth
:=ScaleX(500);
1233 Form
.ClientHeight
:=ScaleY(256);
1236 Info
:=TLabel
.Create(Form
);
1242 Caption
:='The following applications use files that need to be removed, please close them.';
1245 ContinueButton
:=TButton
.Create(Form
);
1246 with ContinueButton
do begin
1248 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1249 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1252 Caption
:='Continue';
1256 ExitButton
:=TButton
.Create(Form
);
1257 with ExitButton
do begin
1259 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1260 Top
:=ContinueButton
.Top
;
1264 ModalResult
:=mrCancel
;
1268 RefreshButton
:=TButton
.Create(Form
);
1269 with RefreshButton
do begin
1272 Top
:=ExitButton
.Top
;
1276 OnClick
:=@RefreshProcessList
;
1279 ProcessesListBox
:=TListBox
.Create(Form
);
1280 with ProcessesListBox
do begin
1283 Top
:=Info
.Top
+Info
.Height
+11;
1284 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1285 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1288 Form
.ActiveControl
:=ContinueButton
;
1290 RefreshProcessList(NIL);
1291 if GetArrayLength(Processes
)>0 then begin
1292 // Now that these dialogs are going
to be shown
, we should probably
1293 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1294 // unfortunately that
is not possible
with Inno Setup currently
.
1295 Result
:=(Form
.ShowModal()=mrOk
);
1297 // Note
: The number
of processes might have changed during a refresh
.
1298 if Result
and (GetArrayLength(Processes
)>0) then begin
1299 Result
:=(SuppressibleMsgBox(
1300 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1301 'Are you sure you want to continue anyway?'
1315 // Even though the name
of this
function suggests otherwise most
of the
1316 // code below
is only executed right before the actual uninstallation
.
1317 // This happens because
of the
if-guard right
in the beginning
of this
1319 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1321 AppDir
,FileName
,Msg
:String;
1322 EnvPath
:TArrayOfString
;
1325 if CurUninstallStep
<>usUninstall
then begin
1329 // Reset the console
font (the FontType
is reset
in the Registry section
).
1330 if IsComponentInstalled('consolefont') then begin
1331 if SuppressibleMsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
,IDYES
)=IDYES
then begin
1332 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1333 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1334 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1339 Modify the environment
1341 This must happen no later than usUninstall to make
1342 "ChangesEnvironment=yes" not happend before the change!
1345 AppDir
:=ExpandConstant('{app}');
1346 FileName
:=AppDir
+'\setup.ini';
1348 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1349 DeleteMarkedEnvString('GIT_SSH
');
1350 DeleteMarkedEnvString('SVN_SSH
');
1352 // Get the current user's directories
in PATH
.
1353 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1355 // Remove the installation directory from PATH
in any
case, even
if it
1356 // was
not added by the installer
.
1357 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1358 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1363 // Reset the current user
's directories in PATH.
1364 if not SetEnvStrings('PATH
',EnvPath,True,IsAdminLoggedOn,True) then begin
1365 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1367 // This is not a critical error, so just notify the user and continue.
1368 SuppressibleMsgBox(Msg,mbError,MB_OK,IDOK);
1372 // Reset the current user's HOME
if we modified it
.
1373 DeleteMarkedEnvString('HOME');
1375 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1376 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1378 // This
is not a critical error
, so just notify the user
and continue
.
1379 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1384 Delete the Windows Explorer integrations
1387 DeleteContextMenuEntries
;
1389 if isWin64
then begin
1390 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1392 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1394 if FileExists(FileName
) then begin
1395 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1396 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1398 // This
is not a critical error
, so just notify the user
and continue
.
1399 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);
1403 if not DeleteFile(FileName
) then begin
1404 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1406 // This
is not a critical error
, so just notify the user
and continue
.
1407 SuppressibleMsgBox(Msg
,mbError
,MB_OK
,IDOK
);