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 COMP_CONSOLE_FONT
'Use a TrueType font in all console windows (not only for Git Bash)'
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 dummy type to avoid getting the default ones.
61 Name
: custom
; Description
: Custom installation
; Flags
: iscustom
64 Name
: icons
; Description
: Additional icons
; Types
: custom
65 Name
: icons\quicklaunch
; Description
: In the Quick Launch
; Types
: custom
66 Name
: icons\desktop
; Description
: On the Desktop
; Types
: custom
67 Name
: ext
; Description
: Windows Explorer integration
; Types
: custom
68 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: custom
69 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: custom
70 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: custom
71 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: custom
72 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: custom
73 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: custom
74 Name
: consolefont
; Description
: {#COMP_CONSOLE_FONT}; Types
: custom
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
: createvalueifdoesntexist 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
: createvalueifdoesntexist 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 procedure DeleteFromVirtualStore
;
177 VirtualStore
,FileName
:String;
180 VirtualStore
:=AddBackslash(ExpandConstant('{localappdata}'))+'VirtualStore';
181 FileName
:=ExpandConstant(CurrentFileName
);
182 DriveChars
:=Length(ExtractFileDrive(FileName
));
183 if DriveChars
>0 then begin
184 Delete(FileName
,1,DriveChars
);
185 FileName
:=VirtualStore
+FileName
;
186 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
187 Log('Line {#__LINE__}: Unable delete "'+FileName
+'".');
188 // This
is not a critical error
, the user can probably fix it manually
,
194 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
196 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
198 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
201 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
202 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
214 // Git line ending conversion options
.
217 GC_CRLFCommitAsIs
= 3;
219 // BindImageEx API constants
.
220 BIND_NO_BOUND_IMPORTS
= $00000001;
221 BIND_NO_UPDATE
= $00000002;
222 BIND_ALL_IMAGES
= $00000004;
223 BIND_CACHE_IMPORT_DLLS
= $00000008;
226 // Wizard page
and variables
for the Path options
.
227 PathPage
:TWizardPage
;
228 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
230 // Wizard page
and variables
for the SSH options
.
231 PuTTYPage
:TWizardPage
;
232 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
235 // Wizard page
and variables
for the line ending conversion options
.
236 CRLFPage
:TWizardPage
;
237 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
239 // Wizard page
and variables
for the processes page
.
241 Processes
:ProcessList
;
242 ProcessesPage
:TWizardPage
;
243 ProcessesListBox
:TListBox
;
244 ProcessesRefresh
,ContinueButton
:TButton
;
246 procedure BrowseForPuTTYFolder(Sender
:TObject
);
250 Path
:=ExtractFilePath(EdtPlink
.Text);
251 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
252 if FileExists(Path
+'\TortoisePlink.exe') then begin
253 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
254 RdbSSH
[GS_Plink
].Checked
:=True;
255 end else if FileExists(Path
+'\plink.exe') then begin
256 EdtPlink
.Text:=Path
+'\plink.exe';
257 RdbSSH
[GS_Plink
].Checked
:=True;
259 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
263 procedure DeleteContextMenuEntries
;
265 AppDir
,Command
,Msg
:String;
268 AppDir
:=ExpandConstant('{app}');
270 if IsAdminLoggedOn
then begin
271 RootKey
:=HKEY_LOCAL_MACHINE
;
273 RootKey
:=HKEY_CURRENT_USER
;
277 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command
);
278 if Pos(AppDir
,Command
)>0 then begin
279 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
280 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash Here" shell extension.';
281 MsgBox(Msg
,mbError
,MB_OK
);
283 // This
is not a critical error
, the user can probably fix it manually
,
289 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command
);
290 if Pos(AppDir
,Command
)>0 then begin
291 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
292 Msg
:='Line {#__LINE__}: Unable to remove "Git GUI Here" shell extension.';
293 MsgBox(Msg
,mbError
,MB_OK
);
295 // This
is not a critical error
, the user can probably fix it manually
,
301 procedure RefreshProcessList(Sender
:TObject
);
303 Version
:TWindowsVersion
;
304 Modules
:TArrayOfString
;
305 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
308 ManualClosingRequired
:Boolean;
310 GetWindowsVersionEx(Version
);
312 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
313 if Version
.Major
>=6 then begin
314 SetArrayLength(Modules
,5);
315 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
316 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
317 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
318 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
319 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
320 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
322 SetArrayLength(Modules
,3);
323 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
324 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
325 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
326 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
328 SetArrayLength(Modules
,2);
329 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
330 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
331 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
333 // Misuse the
"Restartable" flag
to indicate which processes are required
334 // to be closed before setup can continue
, and which just should be closed
335 // in order
to make changes take effect immediately
.
336 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
337 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
338 Processes
[i
]:=ProcsCloseRequired
[i
];
339 Processes
[i
].Restartable
:=False;
341 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
342 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
343 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
347 ManualClosingRequired
:=False;
349 ProcessesListBox
.Items
.Clear
;
350 if (Sender
=NIL) or (SessionHandle
>0) then begin
351 for i
:=0 to GetArrayLength(Processes
)-1 do begin
352 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
353 if Processes
[i
].Restartable
then begin
354 Caption
:=Caption
+', closing is optional';
356 Caption
:=Caption
+', closing is required';
357 ManualClosingRequired
:=True;
359 Caption
:=Caption
+')';
360 ProcessesListBox
.Items
.Append(Caption
);
364 if ContinueButton
<>NIL then begin
365 ContinueButton
.Enabled
:=not ManualClosingRequired
;
373 procedure InitializeWizard
;
376 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
377 LblOpenSSH
,LblPlink
:TLabel
;
378 PuTTYSessions
:TArrayOfString
;
379 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
384 PrevPageID
:=wpSelectProgramGroup
;
387 * Create a custom page for modifying the environment.
390 PathPage
:=CreateCustomPage(
392 'Adjusting your PATH environment',
393 'How would you like to use Git from the command line?'
395 PrevPageID
:=PathPage
.ID
;
398 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
399 with RdbPath
[GP_BashOnly
] do begin
400 Parent
:=PathPage
.Surface
;
401 Caption
:='Use Git Bash only';
406 Font
.Style
:=[fsBold
];
410 LblGitBash
:=TLabel
.Create(PathPage
);
411 with LblGitBash
do begin
412 Parent
:=PathPage
.Surface
;
414 'This is the most conservative choice if you are concerned about the stability' + #
13 +
415 'of your system. Your PATH will not be modified.';
423 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
424 with RdbPath
[GP_Cmd
] do begin
425 Parent
:=PathPage
.Surface
;
426 Caption
:='Run Git from the Windows Command Prompt';
431 Font
.Style
:=[fsBold
];
434 LblGitCmd
:=TLabel
.Create(PathPage
);
435 with LblGitCmd
do begin
436 Parent
:=PathPage
.Surface
;
438 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
439 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
440 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
448 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
449 with RdbPath
[GP_CmdTools
] do begin
450 Parent
:=PathPage
.Surface
;
451 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
456 Font
.Style
:=[fsBold
];
459 LblGitCmdTools
:=TLabel
.Create(PathPage
);
460 with LblGitCmdTools
do begin
461 Parent
:=PathPage
.Surface
;
462 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
468 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
469 with LblGitCmdToolsWarn
do begin
470 Parent
:=PathPage
.Surface
;
472 'Warning: This will override Windows tools like find.exe and' + #
13 +
473 'sort.exe. Select this option only if you understand the implications.';
479 Font
.Style
:=[fsBold
];
482 // Restore the setting chosen during a previous install
.
483 Data
:=GetPreviousData('Path Option','BashOnly');
484 if Data
='BashOnly' then begin
485 RdbPath
[GP_BashOnly
].Checked
:=True;
486 end else if Data
='Cmd' then begin
487 RdbPath
[GP_Cmd
].Checked
:=True;
488 end else if Data
='CmdTools' then begin
489 RdbPath
[GP_CmdTools
].Checked
:=True;
493 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
494 * if at least one PuTTY session is found in the Registry.
497 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
498 PuTTYPage
:=CreateCustomPage(
500 'Choosing the SSH executable',
501 'Which Secure Shell client program would you like Git to use?'
503 PrevPageID
:=PuTTYPage
.ID
;
506 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
507 with RdbSSH
[GS_OpenSSH
] do begin
508 Parent
:=PuTTYPage
.Surface
;
509 Caption
:='Use OpenSSH';
514 Font
.Style
:=[fsBold
];
518 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
519 with LblOpenSSH
do begin
520 Parent
:=PuTTYPage
.Surface
;
522 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
523 'environment variables will not be modified.';
531 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
532 with RdbSSH
[GS_Plink
] do begin
533 Parent
:=PuTTYPage
.Surface
;
534 Caption
:='Use (Tortoise)Plink';
539 Font
.Style
:=[fsBold
];
542 LblPlink
:=TLabel
.Create(PuTTYPage
);
543 with LblPlink
do begin
544 Parent
:=PuTTYPage
.Surface
;
546 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
547 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
548 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
549 'variables will be adjusted to point to the following executable:';
555 EdtPlink
:=TEdit
.Create(PuTTYPage
);
556 with EdtPlink
do begin
557 Parent
:=PuTTYPage
.Surface
;
558 Text:=GetPuTTYLocation
;
559 if not FileExists(Text) then begin
567 BtnPlink
:=TButton
.Create(PuTTYPage
);
568 with BtnPlink
do begin
569 Parent
:=PuTTYPage
.Surface
;
571 OnClick
:=@BrowseForPuTTYFolder
;
578 // Restore the setting chosen during a previous install
.
579 Data
:=GetPreviousData('SSH Option','OpenSSH');
580 if Data
='OpenSSH' then begin
581 RdbSSH
[GS_OpenSSH
].Checked
:=True;
582 end else if Data
='Plink' then begin
583 RdbSSH
[GS_Plink
].Checked
:=True;
590 * Create a custom page for the core.autocrlf setting.
593 CRLFPage
:=CreateCustomPage(
595 'Configuring the line ending conversions',
596 'How should Git treat line endings in text files?'
598 PrevPageID
:=CRLFPage
.ID
;
601 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
602 with RdbCRLF
[GC_CRLFAlways
] do begin
603 Parent
:=CRLFPage
.Surface
;
604 Caption
:='Checkout Windows-style, commit Unix-style line endings';
609 Font
.Style
:=[fsBold
];
613 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
614 with LblCRLFAlways
do begin
615 Parent
:=CRLFPage
.Surface
;
617 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
618 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
619 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
627 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
628 with RdbCRLF
[GC_LFOnly
] do begin
629 Parent
:=CRLFPage
.Surface
;
630 Caption
:='Checkout as-is, commit Unix-style line endings';
635 Font
.Style
:=[fsBold
];
639 LblLFOnly
:=TLabel
.Create(CRLFPage
);
640 with LblLFOnly
do begin
641 Parent
:=CRLFPage
.Surface
;
643 'Git will not perform any conversion when checking out text files. When' + #
13 +
644 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
645 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
653 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
654 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
655 Parent
:=CRLFPage
.Surface
;
656 Caption
:='Checkout as-is, commit as-is';
661 Font
.Style
:=[fsBold
];
665 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
666 with LblCRLFCommitAsIs
do begin
667 Parent
:=CRLFPage
.Surface
;
669 'Git will not perform any conversions when checking out or committing' + #
13 +
670 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
671 'projects ("core.autocrlf" is set to "false").';
678 // Restore the setting chosen during a previous install
.
679 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
680 if Data
='LFOnly' then begin
681 RdbCRLF
[GC_LFOnly
].Checked
:=True;
682 end else if Data
='CRLFAlways' then begin
683 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
684 end else if Data
='CRLFCommitAsIs' then begin
685 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
689 * Create a custom page for finding the processes that lock a module.
692 ProcessesPage
:=CreateCustomPage(
694 'Replacing in-use files',
695 'The following applications use files that need to be replaced, please close them.'
698 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
699 with ProcessesListBox
do begin
700 Parent
:=ProcessesPage
.Surface
;
701 Width
:=ProcessesPage
.SurfaceWidth
;
702 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
705 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
706 with ProcessesRefresh
do begin
708 Width
:=WizardForm
.CancelButton
.Width
;
709 Height
:=WizardForm
.CancelButton
.Height
;
710 Top
:=WizardForm
.CancelButton
.Top
;
711 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
713 OnClick
:=@RefreshProcessList
;
716 // This button
is only used by the uninstaller
.
719 // Initially hide the Refresh button
, show it when the process page becomes current
.
720 ProcessesRefresh
.Hide
;
723 function ShouldSkipPage(PageID
:Integer):Boolean;
725 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
726 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
727 RefreshProcessList(NIL);
728 Result
:=(GetArrayLength(Processes
)=0);
734 procedure CurPageChanged(CurPageID
:Integer);
738 if CurPageID
=wpSelectDir
then begin
739 if not IsDirWritable(WizardDirValue
) then begin
740 // If the default directory
is not writable
, choose another default that most likely
is.
741 // This will be checked later again when the user clicks
"Next".
742 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
746 // Uncheck the console font option by default
.
747 if CurPageID
=wpSelectComponents
then begin
748 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
749 if WizardForm
.ComponentsList
.ItemCaption
[i
]='{#COMP_CONSOLE_FONT}' then begin
750 WizardForm
.ComponentsList
.Checked
[i
]:=False;
756 // Show the
"Refresh" button only on the processes page
.
757 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
758 ProcessesRefresh
.Show
;
760 ProcessesRefresh
.Hide
;
764 function NextButtonClick(CurPageID
:Integer):Boolean;
767 Version
:TWindowsVersion
;
771 if CurPageID
=wpSelectDir
then begin
772 if not IsDirWritable(WizardDirValue
) then begin
774 'The specified installation directory does not seem to be writable. ' +
775 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
784 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
785 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
786 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
787 if not Result
then begin
788 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
790 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
791 // It would have been nicer
to just disable the
"Next" button
, but the
792 // WizardForm
exports the button just
read-only
.
793 for i
:=0 to GetArrayLength(Processes
)-1 do begin
794 if not Processes
[i
].Restartable
then begin
795 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
801 Result
:=(GetArrayLength(Processes
)=0);
803 if not Result
then begin
804 GetWindowsVersionEx(Version
);
805 if Version
.Major
>=6 then begin
807 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
808 'Are you sure you want to continue?',
814 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
815 'Are you sure you want to continue anyway?',
824 procedure CurStepChanged(CurStep
:TSetupStep
);
826 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
827 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
832 Version
:TWindowsVersion
;
834 if CurStep
=ssInstall
then begin
835 // Shutdown locking processes just before the actual installation starts
.
836 if SessionHandle
>0 then try
837 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
839 Log('Line {#__LINE__}: RmShutdown not supported.');
845 // Make sure the code below
is only executed just after the actual installation finishes
.
846 if CurStep
<>ssPostInstall
then begin
850 AppDir
:=ExpandConstant('{app}');
853 Bind the imported function addresses
857 DllPath
:=ExpandConstant('{app}\bin;{sys}');
859 // Load the list
of images from a
text file.
860 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
861 if LoadStringsFromFile(FileName
,ImageNames
) then begin
862 Count
:=GetArrayLength(ImageNames
)-1;
863 for i
:=0 to Count
do begin
864 FileName
:=AppDir
+'\'+ImageNames[i];
865 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
866 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
871 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
878 // Load the built-ins from a text file.
879 FileName:=AppDir+'\
{#APP_BUILTINS}';
880 if LoadStringsFromFile(FileName,BuiltIns) then begin
881 Count:=GetArrayLength(BuiltIns)-1;
883 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
884 for i:=0 to Count do begin
885 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
886 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
887 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
891 // Create built
-ins
as aliases
for git
.exe
.
892 for i
:=0 to Count
do begin
893 FileName
:=AppDir
+'\'+BuiltIns[i];
895 // Delete any existing built-in.
896 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
897 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
902 // This will throw an exception on pre-Win2k systems.
903 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
906 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
909 if not LinkCreated then begin
910 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
911 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
912 // This is not a critical error, Git could basically be used without the
913 // aliases for built-ins, so we continue.
918 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
919 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
921 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
922 FileName:=AppDir+'\bin
\'+FindRec
.name
;
923 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
924 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
927 until not FindNext(FindRec
);
931 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
932 MsgBox(Msg
,mbError
,MB_OK
);
934 // This
is not a critical error
, Git could basically be used without the
935 // aliases
for built
-ins
, so we continue
.
942 if RdbCRLF
[GC_LFOnly
].checked
then begin
943 Cmd
:='core.autocrlf input';
944 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
945 Cmd
:='core.autocrlf true';
947 Cmd
:='core.autocrlf false';
949 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
950 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
951 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
952 MsgBox(Msg
,mbError
,MB_OK
);
954 // This
is not a critical error
, the user can probably fix it manually
,
959 Modify the environment
961 This must happen no later than ssPostInstall to make
962 "ChangesEnvironment=yes" not happend before the change!
965 FileName
:=AppDir
+'\setup.ini';
967 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
968 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
969 if (GetArrayLength(EnvSSH
)=1) and
970 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
971 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
972 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
973 MsgBox(Msg
,mbError
,MB_OK
);
975 // This
is not a critical error
, the user can probably fix it manually
,
980 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
981 if (GetArrayLength(EnvSSH
)=1) and
982 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
983 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
984 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
985 MsgBox(Msg
,mbError
,MB_OK
);
987 // This
is not a critical error
, the user can probably fix it manually
,
992 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
993 SetArrayLength(EnvSSH
,1);
994 EnvSSH
[0]:=EdtPlink
.Text;
996 // Set GIT_SSH
as specified by the user
.
997 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
998 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
999 MsgBox(Msg
,mbError
,MB_OK
);
1001 // This
is not a critical error
, the user can probably fix it manually
,
1005 // Mark that we have changed GIT_SSH by writing its value
to a
file.
1006 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
1007 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1008 MsgBox(Msg
,mbError
,MB_OK
);
1010 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1014 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
1015 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
1016 MsgBox(Msg
,mbError
,MB_OK
);
1018 // This
is not a critical error
, the user can probably fix it manually
,
1022 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1023 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1024 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1025 MsgBox(Msg
,mbError
,MB_OK
);
1027 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1032 // Get the current user
's directories in PATH.
1033 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1035 // First, remove the installation directory from PATH in any case.
1036 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1037 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1042 // Delete HOME if a previous installation modified it.
1043 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1044 if (GetArrayLength(EnvHome)=1) and
1045 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1046 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1047 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1048 MsgBox(Msg,mbError,MB_OK);
1050 // This is not a critical error, the user can probably fix it manually,
1055 // Modify the PATH variable as requested by the user.
1056 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1057 i:=GetArrayLength(EnvPath);
1058 SetArrayLength(EnvPath,i+1);
1060 // List \cmd before \bin so \cmd has higher priority and programs in
1061 // there will be called in favor of those in \bin.
1062 EnvPath[i]:=AppDir+'\cmd
';
1064 if RdbPath[GP_CmdTools].Checked then begin
1065 SetArrayLength(EnvPath,i+2);
1066 EnvPath[i+1]:=AppDir+'\bin
';
1068 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1069 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1070 i:=GetArrayLength(EnvHome);
1071 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1072 SetArrayLength(EnvHome,1);
1073 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1074 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1075 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1076 MsgBox(Msg,mbError,MB_OK);
1078 // This is not a critical error, the user can probably fix it manually,
1082 // Mark that we have changed HOME.
1083 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1084 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1085 MsgBox(Msg,mbError,MB_OK);
1087 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1094 // Set the current user's PATH directories
.
1095 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1096 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1097 MsgBox(Msg
,mbError
,MB_OK
);
1099 // This
is not a critical error
, the user can probably fix it manually
,
1104 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1107 GetWindowsVersionEx(Version
);
1108 if Version
.Major
<6 then begin
1109 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1110 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1112 Cmd
:=AppDir
+'\bin\sh.exe';
1113 TempName
:='--login -i';
1115 FileName
:=AppDir
+'\etc\git.ico';
1117 if IsComponentSelected('icons\quicklaunch') then begin
1119 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1123 , '%HOMEDRIVE%%HOMEPATH%'
1129 if IsComponentSelected('icons\desktop') then begin
1131 GetShellFolder('desktop')+'\Git Bash.lnk'
1135 , '%HOMEDRIVE%%HOMEPATH%'
1142 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1143 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1144 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1146 AppDir
+'\Git Bash.lnk'
1157 Create the Windows Explorer integrations
1160 if IsAdminLoggedOn
then begin
1161 RootKey
:=HKEY_LOCAL_MACHINE
;
1163 RootKey
:=HKEY_CURRENT_USER
;
1166 if IsComponentSelected('ext\reg\shellhere') then begin
1167 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
1168 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','','"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"')) then begin
1169 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1170 MsgBox(Msg
,mbError
,MB_OK
);
1172 // This
is not a critical error
, the user can probably fix it manually
,
1177 if IsComponentSelected('ext\reg\guihere') then begin
1178 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
1179 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','','"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"')) then begin
1180 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1181 MsgBox(Msg
,mbError
,MB_OK
);
1183 // This
is not a critical error
, the user can probably fix it manually
,
1188 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1189 if IsComponentSelected('ext\cheetah') then begin
1190 DeleteContextMenuEntries
;
1192 if isWin64
then begin
1193 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1195 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1197 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1198 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1203 Restart any processes that were shut down via the Restart Manager
1206 if SessionHandle
>0 then try
1207 RmRestart(SessionHandle
,0,0);
1208 RmEndSession(SessionHandle
);
1210 Log('Line {#__LINE__}: RmRestart not supported.');
1214 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1218 // Git Path options
.
1220 if RdbPath
[GP_BashOnly
].Checked
then begin
1222 end else if RdbPath
[GP_Cmd
].Checked
then begin
1224 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1227 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1231 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1233 end else if RdbSSH
[GS_Plink
].Checked
then begin
1236 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1238 // Line ending conversion options
.
1240 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1242 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1244 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1245 Data
:='CRLFCommitAsIs';
1247 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1254 function InitializeUninstall
:Boolean;
1258 ExitButton
,RefreshButton
:TButton
;
1262 Form
:=CreateCustomForm
;
1264 Form
.Caption
:='Git Uninstall: Removing in-use files';
1265 Form
.ClientWidth
:=ScaleX(500);
1266 Form
.ClientHeight
:=ScaleY(256);
1269 Info
:=TLabel
.Create(Form
);
1275 Caption
:='The following applications use files that need to be removed, please close them.';
1278 ContinueButton
:=TButton
.Create(Form
);
1279 with ContinueButton
do begin
1281 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1282 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1285 Caption
:='Continue';
1289 ExitButton
:=TButton
.Create(Form
);
1290 with ExitButton
do begin
1292 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1293 Top
:=ContinueButton
.Top
;
1297 ModalResult
:=mrCancel
;
1301 RefreshButton
:=TButton
.Create(Form
);
1302 with RefreshButton
do begin
1305 Top
:=ExitButton
.Top
;
1309 OnClick
:=@RefreshProcessList
;
1312 ProcessesListBox
:=TListBox
.Create(Form
);
1313 with ProcessesListBox
do begin
1316 Top
:=Info
.Top
+Info
.Height
+11;
1317 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1318 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1321 Form
.ActiveControl
:=ContinueButton
;
1323 RefreshProcessList(NIL);
1324 if GetArrayLength(Processes
)>0 then begin
1325 // Now that these dialogs are going
to be shown
, we should probably
1326 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1327 // unfortunately that
is not possible
with Inno Setup currently
.
1328 Result
:=(Form
.ShowModal()=mrOk
);
1330 // Note
: The number
of processes might have changed during a refresh
.
1331 if Result
and (GetArrayLength(Processes
)>0) then begin
1333 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1334 'Are you sure you want to continue anyway?',
1347 // Even though the name
of this
function suggests otherwise most
of the
1348 // code below
is only executed right before the actual uninstallation
.
1349 // This happens because
of the
if-guard right
in the beginning
of this
1351 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1353 AppDir
,FileName
,Msg
:String;
1354 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1357 if CurUninstallStep
<>usUninstall
then begin
1361 // Reset the console
font (the FontType
is reset
in the Registry section
).
1362 if IsComponentInstalled('consolefont') then begin
1363 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1364 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1365 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1366 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1371 Modify the environment
1373 This must happen no later than usUninstall to make
1374 "ChangesEnvironment=yes" not happend before the change!
1377 AppDir
:=ExpandConstant('{app}');
1378 FileName
:=AppDir
+'\setup.ini';
1380 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1381 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1382 if (GetArrayLength(EnvSSH)=1) and
1383 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1384 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1385 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1386 MsgBox(Msg,mbError,MB_OK);
1388 // This is not a critical error, the user can probably fix it manually,
1393 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1394 if (GetArrayLength(EnvSSH)=1) and
1395 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1396 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1397 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1398 MsgBox(Msg,mbError,MB_OK);
1400 // This is not a critical error, the user can probably fix it manually,
1405 // Get the current user's directories
in PATH
.
1406 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1408 // Remove the installation directory from PATH
in any
case, even
if it
1409 // was
not added by the installer
.
1410 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1411 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1416 // Reset the current user
's directories in PATH.
1417 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1418 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1419 MsgBox(Msg,mbError,MB_OK);
1421 // This is not a critical error, the user can probably fix it manually,
1425 // Reset the current user's HOME
if we modified it
.
1426 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1427 if (GetArrayLength(EnvHome
)=1) and
1428 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1429 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1430 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1431 MsgBox(Msg
,mbError
,MB_OK
);
1433 // This
is not a critical error
, the user can probably fix it manually
,
1438 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1439 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1440 MsgBox(Msg
,mbError
,MB_OK
);
1442 // This
is not a critical error
, the user can probably fix it manually
,
1447 Delete the Windows Explorer integrations
1450 DeleteContextMenuEntries
;
1452 if isWin64
then begin
1453 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1455 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1457 if FileExists(FileName
) then begin
1458 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1459 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1460 MsgBox(Msg
,mbError
,MB_OK
);
1464 if not DeleteFile(FileName
) then begin
1465 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1466 MsgBox(Msg
,mbError
,MB_OK
);