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 (Tortoise)Plink.exe.'
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 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('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
263 procedure DeleteContextMenuEntries
;
265 AppDir
,Command
,Msg
:String;
269 AppDir
:=ExpandConstant('{app}');
271 if IsAdminLoggedOn
then begin
272 RootKey
:=HKEY_LOCAL_MACHINE
;
274 RootKey
:=HKEY_CURRENT_USER
;
277 SetArrayLength(Keys
,4);
278 Keys
[0]:='SOFTWARE\Classes\Directory\shell\git_shell';
279 Keys
[1]:='SOFTWARE\Classes\Directory\Background\shell\git_shell';
280 Keys
[2]:='SOFTWARE\Classes\Directory\shell\git_gui';
281 Keys
[3]:='SOFTWARE\Classes\Directory\Background\shell\git_gui';
283 for i
:=0 to Length(Keys
)-1 do begin
285 RegQueryStringValue(RootKey
,Keys
[i
]+'\command','',Command
);
286 if Pos(AppDir
,Command
)>0 then begin
287 if not RegDeleteKeyIncludingSubkeys(RootKey
,Keys
[i
]) then begin
288 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash / GUI Here" shell extension.';
289 MsgBox(Msg
,mbError
,MB_OK
);
291 // This
is not a critical error
, the user can probably fix it manually
,
298 procedure RefreshProcessList(Sender
:TObject
);
300 Version
:TWindowsVersion
;
301 Modules
:TArrayOfString
;
302 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
305 ManualClosingRequired
:Boolean;
307 GetWindowsVersionEx(Version
);
309 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
310 if Version
.Major
>=6 then begin
311 SetArrayLength(Modules
,5);
312 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
313 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
314 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
315 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
316 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
317 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
319 SetArrayLength(Modules
,3);
320 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
321 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
322 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
323 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
325 SetArrayLength(Modules
,2);
326 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
327 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
328 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
330 // Misuse the
"Restartable" flag
to indicate which processes are required
331 // to be closed before setup can continue
, and which just should be closed
332 // in order
to make changes take effect immediately
.
333 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
334 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
335 Processes
[i
]:=ProcsCloseRequired
[i
];
336 Processes
[i
].Restartable
:=False;
338 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
339 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
340 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
344 ManualClosingRequired
:=False;
346 ProcessesListBox
.Items
.Clear
;
347 if (Sender
=NIL) or (SessionHandle
>0) then begin
348 for i
:=0 to GetArrayLength(Processes
)-1 do begin
349 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
350 if Processes
[i
].Restartable
then begin
351 Caption
:=Caption
+', closing is optional';
353 Caption
:=Caption
+', closing is required';
354 ManualClosingRequired
:=True;
356 Caption
:=Caption
+')';
357 ProcessesListBox
.Items
.Append(Caption
);
361 if ContinueButton
<>NIL then begin
362 ContinueButton
.Enabled
:=not ManualClosingRequired
;
370 procedure InitializeWizard
;
373 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
374 LblOpenSSH
,LblPlink
:TLabel
;
375 PuTTYSessions
:TArrayOfString
;
376 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
381 PrevPageID
:=wpSelectProgramGroup
;
384 * Create a custom page for modifying the environment.
387 PathPage
:=CreateCustomPage(
389 'Adjusting your PATH environment',
390 'How would you like to use Git from the command line?'
392 PrevPageID
:=PathPage
.ID
;
395 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
396 with RdbPath
[GP_BashOnly
] do begin
397 Parent
:=PathPage
.Surface
;
398 Caption
:='Use Git Bash only';
403 Font
.Style
:=[fsBold
];
407 LblGitBash
:=TLabel
.Create(PathPage
);
408 with LblGitBash
do begin
409 Parent
:=PathPage
.Surface
;
411 'This is the most conservative choice if you are concerned about the stability' + #
13 +
412 'of your system. Your PATH will not be modified.';
420 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
421 with RdbPath
[GP_Cmd
] do begin
422 Parent
:=PathPage
.Surface
;
423 Caption
:='Run Git from the Windows Command Prompt';
428 Font
.Style
:=[fsBold
];
431 LblGitCmd
:=TLabel
.Create(PathPage
);
432 with LblGitCmd
do begin
433 Parent
:=PathPage
.Surface
;
435 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
436 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
437 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
445 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
446 with RdbPath
[GP_CmdTools
] do begin
447 Parent
:=PathPage
.Surface
;
448 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
453 Font
.Style
:=[fsBold
];
456 LblGitCmdTools
:=TLabel
.Create(PathPage
);
457 with LblGitCmdTools
do begin
458 Parent
:=PathPage
.Surface
;
459 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
465 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
466 with LblGitCmdToolsWarn
do begin
467 Parent
:=PathPage
.Surface
;
469 'Warning: This will override Windows tools like find.exe and' + #
13 +
470 'sort.exe. Select this option only if you understand the implications.';
476 Font
.Style
:=[fsBold
];
479 // Restore the setting chosen during a previous install
.
480 Data
:=GetPreviousData('Path Option','BashOnly');
481 if Data
='BashOnly' then begin
482 RdbPath
[GP_BashOnly
].Checked
:=True;
483 end else if Data
='Cmd' then begin
484 RdbPath
[GP_Cmd
].Checked
:=True;
485 end else if Data
='CmdTools' then begin
486 RdbPath
[GP_CmdTools
].Checked
:=True;
490 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
491 * if at least one PuTTY session is found in the Registry.
494 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
495 PuTTYPage
:=CreateCustomPage(
497 'Choosing the SSH executable',
498 'Which Secure Shell client program would you like Git to use?'
500 PrevPageID
:=PuTTYPage
.ID
;
503 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
504 with RdbSSH
[GS_OpenSSH
] do begin
505 Parent
:=PuTTYPage
.Surface
;
506 Caption
:='Use OpenSSH';
511 Font
.Style
:=[fsBold
];
515 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
516 with LblOpenSSH
do begin
517 Parent
:=PuTTYPage
.Surface
;
519 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
520 'environment variables will not be modified.';
528 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
529 with RdbSSH
[GS_Plink
] do begin
530 Parent
:=PuTTYPage
.Surface
;
531 Caption
:='Use (Tortoise)Plink';
536 Font
.Style
:=[fsBold
];
539 LblPlink
:=TLabel
.Create(PuTTYPage
);
540 with LblPlink
do begin
541 Parent
:=PuTTYPage
.Surface
;
543 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
544 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
545 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
546 'variables will be adjusted to point to the following executable:';
552 EdtPlink
:=TEdit
.Create(PuTTYPage
);
553 with EdtPlink
do begin
554 Parent
:=PuTTYPage
.Surface
;
555 Text:=GetPreviousData('Plink Path','');
556 if not FileExists(Text) then begin
557 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);
736 if CurPageID
=wpSelectDir
then begin
737 if not IsDirWritable(WizardDirValue
) then begin
738 // If the default directory
is not writable
, choose another default that most likely
is.
739 // This will be checked later again when the user clicks
"Next".
740 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
744 // Show the
"Refresh" button only on the processes page
.
745 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
746 ProcessesRefresh
.Show
;
748 ProcessesRefresh
.Hide
;
752 function NextButtonClick(CurPageID
:Integer):Boolean;
755 Version
:TWindowsVersion
;
759 if CurPageID
=wpSelectDir
then begin
760 if not IsDirWritable(WizardDirValue
) then begin
762 'The specified installation directory does not seem to be writable. ' +
763 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
772 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
773 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
774 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
775 if not Result
then begin
776 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
778 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
779 // It would have been nicer
to just disable the
"Next" button
, but the
780 // WizardForm
exports the button just
read-only
.
781 for i
:=0 to GetArrayLength(Processes
)-1 do begin
782 if not Processes
[i
].Restartable
then begin
783 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
789 Result
:=(GetArrayLength(Processes
)=0);
791 if not Result
then begin
792 GetWindowsVersionEx(Version
);
793 if Version
.Major
>=6 then begin
795 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
796 'Are you sure you want to continue?',
802 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
803 'Are you sure you want to continue anyway?',
812 procedure CurStepChanged(CurStep
:TSetupStep
);
814 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
815 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
820 Version
:TWindowsVersion
;
822 if CurStep
=ssInstall
then begin
823 // Shutdown locking processes just before the actual installation starts
.
824 if SessionHandle
>0 then try
825 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
827 Log('Line {#__LINE__}: RmShutdown not supported.');
833 // Make sure the code below
is only executed just after the actual installation finishes
.
834 if CurStep
<>ssPostInstall
then begin
838 AppDir
:=ExpandConstant('{app}');
841 Bind the imported function addresses
845 DllPath
:=ExpandConstant('{app}\bin;{sys}');
847 // Load the list
of images from a
text file.
848 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
849 if LoadStringsFromFile(FileName
,ImageNames
) then begin
850 Count
:=GetArrayLength(ImageNames
)-1;
851 for i
:=0 to Count
do begin
852 FileName
:=AppDir
+'\'+ImageNames[i];
853 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
854 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
859 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
866 // Load the built-ins from a text file.
867 FileName:=AppDir+'\
{#APP_BUILTINS}';
868 if LoadStringsFromFile(FileName,BuiltIns) then begin
869 Count:=GetArrayLength(BuiltIns)-1;
871 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
872 for i:=0 to Count do begin
873 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
874 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
875 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
879 // Create built
-ins
as aliases
for git
.exe
.
880 for i
:=0 to Count
do begin
881 FileName
:=AppDir
+'\'+BuiltIns[i];
883 // Delete any existing built-in.
884 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
885 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
890 // This will throw an exception on pre-Win2k systems.
891 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
894 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
897 if not LinkCreated then begin
898 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
899 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
900 // This is not a critical error, Git could basically be used without the
901 // aliases for built-ins, so we continue.
906 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
907 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
909 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
910 FileName:=AppDir+'\bin
\'+FindRec
.name
;
911 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
912 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
915 until not FindNext(FindRec
);
919 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
920 MsgBox(Msg
,mbError
,MB_OK
);
922 // This
is not a critical error
, Git could basically be used without the
923 // aliases
for built
-ins
, so we continue
.
930 if RdbCRLF
[GC_LFOnly
].checked
then begin
931 Cmd
:='core.autocrlf input';
932 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
933 Cmd
:='core.autocrlf true';
935 Cmd
:='core.autocrlf false';
937 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
938 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
939 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
940 MsgBox(Msg
,mbError
,MB_OK
);
942 // This
is not a critical error
, the user can probably fix it manually
,
947 Modify the environment
949 This must happen no later than ssPostInstall to make
950 "ChangesEnvironment=yes" not happend before the change!
953 FileName
:=AppDir
+'\setup.ini';
955 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
956 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
957 if (GetArrayLength(EnvSSH
)=1) and
958 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
959 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
960 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
961 MsgBox(Msg
,mbError
,MB_OK
);
963 // This
is not a critical error
, the user can probably fix it manually
,
968 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
969 if (GetArrayLength(EnvSSH
)=1) and
970 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
971 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
972 Msg
:='Line {#__LINE__}: Unable to reset SVN_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 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
981 SetArrayLength(EnvSSH
,1);
982 EnvSSH
[0]:=EdtPlink
.Text;
984 // Set GIT_SSH
as specified by the user
.
985 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
986 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
987 MsgBox(Msg
,mbError
,MB_OK
);
989 // This
is not a critical error
, the user can probably fix it manually
,
993 // Mark that we have changed GIT_SSH by writing its value
to a
file.
994 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
995 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
996 MsgBox(Msg
,mbError
,MB_OK
);
998 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1002 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
1003 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
1004 MsgBox(Msg
,mbError
,MB_OK
);
1006 // This
is not a critical error
, the user can probably fix it manually
,
1010 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1011 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1012 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1013 MsgBox(Msg
,mbError
,MB_OK
);
1015 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1020 // Get the current user
's directories in PATH.
1021 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1023 // First, remove the installation directory from PATH in any case.
1024 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1025 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1030 // Delete HOME if a previous installation modified it.
1031 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1032 if (GetArrayLength(EnvHome)=1) and
1033 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1034 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1035 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1036 MsgBox(Msg,mbError,MB_OK);
1038 // This is not a critical error, the user can probably fix it manually,
1043 // Modify the PATH variable as requested by the user.
1044 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1045 i:=GetArrayLength(EnvPath);
1046 SetArrayLength(EnvPath,i+1);
1048 // List \cmd before \bin so \cmd has higher priority and programs in
1049 // there will be called in favor of those in \bin.
1050 EnvPath[i]:=AppDir+'\cmd
';
1052 if RdbPath[GP_CmdTools].Checked then begin
1053 SetArrayLength(EnvPath,i+2);
1054 EnvPath[i+1]:=AppDir+'\bin
';
1056 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1057 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1058 i:=GetArrayLength(EnvHome);
1059 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1060 SetArrayLength(EnvHome,1);
1061 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1062 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1063 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1064 MsgBox(Msg,mbError,MB_OK);
1066 // This is not a critical error, the user can probably fix it manually,
1070 // Mark that we have changed HOME.
1071 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1072 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1073 MsgBox(Msg,mbError,MB_OK);
1075 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1082 // Set the current user's PATH directories
.
1083 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1084 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1085 MsgBox(Msg
,mbError
,MB_OK
);
1087 // This
is not a critical error
, the user can probably fix it manually
,
1092 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1095 GetWindowsVersionEx(Version
);
1096 if Version
.Major
<6 then begin
1097 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1098 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1100 Cmd
:=AppDir
+'\bin\sh.exe';
1101 TempName
:='--login -i';
1103 FileName
:=AppDir
+'\etc\git.ico';
1105 if IsComponentSelected('icons\quicklaunch') then begin
1107 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1111 , '%HOMEDRIVE%%HOMEPATH%'
1117 if IsComponentSelected('icons\desktop') then begin
1119 GetShellFolder('desktop')+'\Git Bash.lnk'
1123 , '%HOMEDRIVE%%HOMEPATH%'
1130 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1131 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1132 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1134 AppDir
+'\Git Bash.lnk'
1145 Create the Windows Explorer integrations
1148 if IsAdminLoggedOn
then begin
1149 RootKey
:=HKEY_LOCAL_MACHINE
;
1151 RootKey
:=HKEY_CURRENT_USER
;
1154 if IsComponentSelected('ext\reg\shellhere') then begin
1155 Msg
:='Git Ba&sh Here';
1156 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1157 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1158 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1159 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1160 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1161 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then begin
1162 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1163 MsgBox(Msg
,mbError
,MB_OK
);
1165 // This
is not a critical error
, the user can probably fix it manually
,
1170 if IsComponentSelected('ext\reg\guihere') then begin
1171 Msg
:='Git &GUI Here';
1172 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1173 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1174 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1175 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1176 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1177 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
)) then begin
1178 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1179 MsgBox(Msg
,mbError
,MB_OK
);
1181 // This
is not a critical error
, the user can probably fix it manually
,
1186 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1187 if IsComponentSelected('ext\cheetah') then begin
1188 DeleteContextMenuEntries
;
1190 if isWin64
then begin
1191 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1193 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1195 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1196 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1201 Restart any processes that were shut down via the Restart Manager
1204 if SessionHandle
>0 then try
1205 RmRestart(SessionHandle
,0,0);
1206 RmEndSession(SessionHandle
);
1208 Log('Line {#__LINE__}: RmRestart not supported.');
1212 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1216 // Git Path options
.
1218 if RdbPath
[GP_BashOnly
].Checked
then begin
1220 end else if RdbPath
[GP_Cmd
].Checked
then begin
1222 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1225 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1229 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1231 end else if RdbSSH
[GS_Plink
].Checked
then begin
1233 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1235 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1237 // Line ending conversion options
.
1239 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1241 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1243 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1244 Data
:='CRLFCommitAsIs';
1246 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1253 function InitializeUninstall
:Boolean;
1257 ExitButton
,RefreshButton
:TButton
;
1261 Form
:=CreateCustomForm
;
1263 Form
.Caption
:='Git Uninstall: Removing in-use files';
1264 Form
.ClientWidth
:=ScaleX(500);
1265 Form
.ClientHeight
:=ScaleY(256);
1268 Info
:=TLabel
.Create(Form
);
1274 Caption
:='The following applications use files that need to be removed, please close them.';
1277 ContinueButton
:=TButton
.Create(Form
);
1278 with ContinueButton
do begin
1280 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1281 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1284 Caption
:='Continue';
1288 ExitButton
:=TButton
.Create(Form
);
1289 with ExitButton
do begin
1291 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1292 Top
:=ContinueButton
.Top
;
1296 ModalResult
:=mrCancel
;
1300 RefreshButton
:=TButton
.Create(Form
);
1301 with RefreshButton
do begin
1304 Top
:=ExitButton
.Top
;
1308 OnClick
:=@RefreshProcessList
;
1311 ProcessesListBox
:=TListBox
.Create(Form
);
1312 with ProcessesListBox
do begin
1315 Top
:=Info
.Top
+Info
.Height
+11;
1316 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1317 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1320 Form
.ActiveControl
:=ContinueButton
;
1322 RefreshProcessList(NIL);
1323 if GetArrayLength(Processes
)>0 then begin
1324 // Now that these dialogs are going
to be shown
, we should probably
1325 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1326 // unfortunately that
is not possible
with Inno Setup currently
.
1327 Result
:=(Form
.ShowModal()=mrOk
);
1329 // Note
: The number
of processes might have changed during a refresh
.
1330 if Result
and (GetArrayLength(Processes
)>0) then begin
1332 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1333 'Are you sure you want to continue anyway?',
1346 // Even though the name
of this
function suggests otherwise most
of the
1347 // code below
is only executed right before the actual uninstallation
.
1348 // This happens because
of the
if-guard right
in the beginning
of this
1350 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1352 AppDir
,FileName
,Msg
:String;
1353 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1356 if CurUninstallStep
<>usUninstall
then begin
1360 // Reset the console
font (the FontType
is reset
in the Registry section
).
1361 if IsComponentInstalled('consolefont') then begin
1362 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1363 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1364 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1365 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1370 Modify the environment
1372 This must happen no later than usUninstall to make
1373 "ChangesEnvironment=yes" not happend before the change!
1376 AppDir
:=ExpandConstant('{app}');
1377 FileName
:=AppDir
+'\setup.ini';
1379 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1380 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1381 if (GetArrayLength(EnvSSH)=1) and
1382 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1383 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1384 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1385 MsgBox(Msg,mbError,MB_OK);
1387 // This is not a critical error, the user can probably fix it manually,
1392 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1393 if (GetArrayLength(EnvSSH)=1) and
1394 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1395 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1396 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1397 MsgBox(Msg,mbError,MB_OK);
1399 // This is not a critical error, the user can probably fix it manually,
1404 // Get the current user's directories
in PATH
.
1405 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1407 // Remove the installation directory from PATH
in any
case, even
if it
1408 // was
not added by the installer
.
1409 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1410 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1415 // Reset the current user
's directories in PATH.
1416 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1417 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1418 MsgBox(Msg,mbError,MB_OK);
1420 // This is not a critical error, the user can probably fix it manually,
1424 // Reset the current user's HOME
if we modified it
.
1425 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1426 if (GetArrayLength(EnvHome
)=1) and
1427 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1428 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1429 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1430 MsgBox(Msg
,mbError
,MB_OK
);
1432 // This
is not a critical error
, the user can probably fix it manually
,
1437 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1438 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1439 MsgBox(Msg
,mbError
,MB_OK
);
1441 // This
is not a critical error
, the user can probably fix it manually
,
1446 Delete the Windows Explorer integrations
1449 DeleteContextMenuEntries
;
1451 if isWin64
then begin
1452 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1454 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1456 if FileExists(FileName
) then begin
1457 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1458 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1459 MsgBox(Msg
,mbError
,MB_OK
);
1463 if not DeleteFile(FileName
) then begin
1464 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1465 MsgBox(Msg
,mbError
,MB_OK
);