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 DROP_HANDLER_GUID
'{{86C86720-42A0-1069-A2E8-08002B30309D}'
18 Compression
=lzma2
/ultra
19 LZMAUseSeparateProcess
=yes
20 OutputBaseFilename
={#APP_NAME+'-'+APP_VERSION}
21 OutputDir
={#GetEnv('USERPROFILE')}
23 #ifdef COMPILE_FROM_IDE
24 SourceDir
={#GetEnv('TEMP')}\WinGit
30 AppPublisher
=The Git Development Community
31 AppPublisherURL
={#APP_URL}
32 AppVersion
={#APP_VERSION}
33 ChangesEnvironment
=yes
34 DefaultDirName
={pf}\
{#APP_NAME}
36 DefaultGroupName
={#APP_NAME}
37 DisableProgramGroupPage
=auto
39 InfoBeforeFile
=gpl
-2.0.rtf
40 PrivilegesRequired
=none
41 UninstallDisplayIcon
={app}\etc\git
.ico
42 #ifndef COMPILE_FROM_IDE
43 #
if Pos('-',APP_VERSION
)>0
44 VersionInfoVersion
={#Copy(APP_VERSION,1,Pos('-',APP_VERSION)-1)}
46 VersionInfoVersion
={#APP_VERSION}
51 SetupIconFile
=etc\git
.ico
52 WizardImageBackColor
=clWhite
54 WizardImageFile
=git
.bmp
55 WizardSmallImageFile
=gitsmall
.bmp
58 ; Define a custom type to avoid getting the three default types.
59 Name
: default
; Description
: Default installation
; Flags
: iscustom
62 Name
: icons
; Description
: Additional icons
63 Name
: icons\quicklaunch
; Description
: In the Quick Launch
64 Name
: icons\desktop
; Description
: On the Desktop
65 Name
: ext
; Description
: Windows Explorer integration
; Types
: default
66 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: default
67 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: default
68 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: default
69 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: default
70 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: default
71 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: default
72 Name
: consolefont
; Description
: Use a TrueType font
in all console
windows (not only
for Git Bash
)
75 ; Install files that might be in use during setup under a different name.
76 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
77 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
79 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
80 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion; AfterInstall
: DeleteFromVirtualStore
83 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
84 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
85 Name
: {group}\Git Bash
; Filename
: {app}\bin\sh
.exe
; Parameters
: "--login -i"; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; MinVersion
: 6.0
88 BeveledLabel
={#APP_URL}
89 SetupAppTitle
={#APP_NAME} Setup
90 SetupWindowTitle
={#APP_NAME} Setup
93 ; There is no "Console" key in HKLM.
94 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
95 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
96 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
97 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
99 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
100 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
101 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
102 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
104 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
105 ; is a member of the local Administrators group or not (see the "Check" argument).
107 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
108 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
109 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
110 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
111 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
112 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
113 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
115 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
116 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
117 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
118 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
119 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
120 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
122 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
123 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
124 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
125 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
126 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
127 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
129 ; Associate .sh extension with sh.exe so those files are double-clickable,
130 ; startable from cmd.exe, and when files are dropped on them they are passed
131 ; as arguments to the script.
133 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
134 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
135 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
136 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
137 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
138 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
139 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
141 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
142 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
143 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
144 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
145 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
146 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
147 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
150 ; Delete the built-ins.
151 Type: files; Name
: {app}\bin\git
-*.exe
152 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
153 Type: files; Name
: {app}\libexec\git
-core\git
.exe
155 ; Delete any (temporary) git-cheetah files.
156 Type: files; Name
: {app}\git
-cheetah\
*.*
158 ; Delete any manually created shortcuts.
159 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
160 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
161 Type: files; Name
: {app}\Git Bash
.lnk
163 ; Delete a home directory inside the msysGit directory.
164 Type: dirifempty; Name
: {app}\home\
{username}
165 Type: dirifempty; Name
: {app}\home
168 #include
"helpers.inc.iss"
169 #include
"environment.inc.iss"
170 #include
"putty.inc.iss"
171 #include
"modules.inc.iss"
173 procedure DeleteFromVirtualStore
;
175 VirtualStore
,FileName
:String;
178 VirtualStore
:=AddBackslash(ExpandConstant('{localappdata}'))+'VirtualStore';
179 FileName
:=ExpandConstant(CurrentFileName
);
180 DriveChars
:=Length(ExtractFileDrive(FileName
));
181 if DriveChars
>0 then begin
182 Delete(FileName
,1,DriveChars
);
183 FileName
:=VirtualStore
+FileName
;
184 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
185 Log('Line {#__LINE__}: Unable delete "'+FileName
+'".');
186 // This
is not a critical error
, the user can probably fix it manually
,
192 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
194 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
196 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
199 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
200 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
212 // Git line ending conversion options
.
215 GC_CRLFCommitAsIs
= 3;
217 // BindImageEx API constants
.
218 BIND_NO_BOUND_IMPORTS
= $00000001;
219 BIND_NO_UPDATE
= $00000002;
220 BIND_ALL_IMAGES
= $00000004;
221 BIND_CACHE_IMPORT_DLLS
= $00000008;
224 // Wizard page
and variables
for the Path options
.
225 PathPage
:TWizardPage
;
226 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
228 // Wizard page
and variables
for the SSH options
.
229 PuTTYPage
:TWizardPage
;
230 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
233 // Wizard page
and variables
for the line ending conversion options
.
234 CRLFPage
:TWizardPage
;
235 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
237 // Wizard page
and variables
for the processes page
.
239 Processes
:ProcessList
;
240 ProcessesPage
:TWizardPage
;
241 ProcessesListBox
:TListBox
;
242 ProcessesRefresh
,ContinueButton
:TButton
;
244 procedure BrowseForPuTTYFolder(Sender
:TObject
);
248 Path
:=ExtractFilePath(EdtPlink
.Text);
249 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
250 if FileExists(Path
+'\TortoisePlink.exe') then begin
251 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
252 RdbSSH
[GS_Plink
].Checked
:=True;
253 end else if FileExists(Path
+'\plink.exe') then begin
254 EdtPlink
.Text:=Path
+'\plink.exe';
255 RdbSSH
[GS_Plink
].Checked
:=True;
257 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
261 procedure DeleteContextMenuEntries
;
263 AppDir
,Command
,Msg
:String;
267 AppDir
:=ExpandConstant('{app}');
269 if IsAdminLoggedOn
then begin
270 RootKey
:=HKEY_LOCAL_MACHINE
;
272 RootKey
:=HKEY_CURRENT_USER
;
275 SetArrayLength(Keys
,4);
276 Keys
[0]:='SOFTWARE\Classes\Directory\shell\git_shell';
277 Keys
[1]:='SOFTWARE\Classes\Directory\Background\shell\git_shell';
278 Keys
[2]:='SOFTWARE\Classes\Directory\shell\git_gui';
279 Keys
[3]:='SOFTWARE\Classes\Directory\Background\shell\git_gui';
281 for i
:=0 to Length(Keys
)-1 do begin
283 RegQueryStringValue(RootKey
,Keys
[i
]+'\command','',Command
);
284 if Pos(AppDir
,Command
)>0 then begin
285 if not RegDeleteKeyIncludingSubkeys(RootKey
,Keys
[i
]) then begin
286 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash / GUI Here" shell extension.';
287 MsgBox(Msg
,mbError
,MB_OK
);
289 // This
is not a critical error
, the user can probably fix it manually
,
296 procedure RefreshProcessList(Sender
:TObject
);
298 Version
:TWindowsVersion
;
299 Modules
:TArrayOfString
;
300 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
303 ManualClosingRequired
:Boolean;
305 GetWindowsVersionEx(Version
);
307 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
308 if Version
.Major
>=6 then begin
309 SetArrayLength(Modules
,5);
310 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
311 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
312 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
313 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
314 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
315 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
317 SetArrayLength(Modules
,3);
318 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
319 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
320 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
321 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
323 SetArrayLength(Modules
,2);
324 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
325 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
326 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
328 // Misuse the
"Restartable" flag
to indicate which processes are required
329 // to be closed before setup can continue
, and which just should be closed
330 // in order
to make changes take effect immediately
.
331 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
332 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
333 Processes
[i
]:=ProcsCloseRequired
[i
];
334 Processes
[i
].Restartable
:=False;
336 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
337 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
338 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
342 ManualClosingRequired
:=False;
344 ProcessesListBox
.Items
.Clear
;
345 if (Sender
=NIL) or (SessionHandle
>0) then begin
346 for i
:=0 to GetArrayLength(Processes
)-1 do begin
347 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
348 if Processes
[i
].Restartable
then begin
349 Caption
:=Caption
+', closing is optional';
351 Caption
:=Caption
+', closing is required';
352 ManualClosingRequired
:=True;
354 Caption
:=Caption
+')';
355 ProcessesListBox
.Items
.Append(Caption
);
359 if ContinueButton
<>NIL then begin
360 ContinueButton
.Enabled
:=not ManualClosingRequired
;
368 procedure InitializeWizard
;
371 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
372 LblOpenSSH
,LblPlink
:TLabel
;
373 PuTTYSessions
:TArrayOfString
;
374 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
379 PrevPageID
:=wpSelectProgramGroup
;
382 * Create a custom page for modifying the environment.
385 PathPage
:=CreateCustomPage(
387 'Adjusting your PATH environment',
388 'How would you like to use Git from the command line?'
390 PrevPageID
:=PathPage
.ID
;
393 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
394 with RdbPath
[GP_BashOnly
] do begin
395 Parent
:=PathPage
.Surface
;
396 Caption
:='Use Git Bash only';
401 Font
.Style
:=[fsBold
];
405 LblGitBash
:=TLabel
.Create(PathPage
);
406 with LblGitBash
do begin
407 Parent
:=PathPage
.Surface
;
409 'This is the most conservative choice if you are concerned about the stability' + #
13 +
410 'of your system. Your PATH will not be modified.';
418 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
419 with RdbPath
[GP_Cmd
] do begin
420 Parent
:=PathPage
.Surface
;
421 Caption
:='Run Git from the Windows Command Prompt';
426 Font
.Style
:=[fsBold
];
429 LblGitCmd
:=TLabel
.Create(PathPage
);
430 with LblGitCmd
do begin
431 Parent
:=PathPage
.Surface
;
433 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
434 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
435 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
443 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
444 with RdbPath
[GP_CmdTools
] do begin
445 Parent
:=PathPage
.Surface
;
446 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
451 Font
.Style
:=[fsBold
];
454 LblGitCmdTools
:=TLabel
.Create(PathPage
);
455 with LblGitCmdTools
do begin
456 Parent
:=PathPage
.Surface
;
457 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
463 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
464 with LblGitCmdToolsWarn
do begin
465 Parent
:=PathPage
.Surface
;
467 'Warning: This will override Windows tools like find.exe and' + #
13 +
468 'sort.exe. Select this option only if you understand the implications.';
474 Font
.Style
:=[fsBold
];
477 // Restore the setting chosen during a previous install
.
478 Data
:=GetPreviousData('Path Option','BashOnly');
479 if Data
='BashOnly' then begin
480 RdbPath
[GP_BashOnly
].Checked
:=True;
481 end else if Data
='Cmd' then begin
482 RdbPath
[GP_Cmd
].Checked
:=True;
483 end else if Data
='CmdTools' then begin
484 RdbPath
[GP_CmdTools
].Checked
:=True;
488 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
489 * if at least one PuTTY session is found in the Registry.
492 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
493 PuTTYPage
:=CreateCustomPage(
495 'Choosing the SSH executable',
496 'Which Secure Shell client program would you like Git to use?'
498 PrevPageID
:=PuTTYPage
.ID
;
501 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
502 with RdbSSH
[GS_OpenSSH
] do begin
503 Parent
:=PuTTYPage
.Surface
;
504 Caption
:='Use OpenSSH';
509 Font
.Style
:=[fsBold
];
513 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
514 with LblOpenSSH
do begin
515 Parent
:=PuTTYPage
.Surface
;
517 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
518 'environment variables will not be modified.';
526 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
527 with RdbSSH
[GS_Plink
] do begin
528 Parent
:=PuTTYPage
.Surface
;
529 Caption
:='Use (Tortoise)Plink';
534 Font
.Style
:=[fsBold
];
537 LblPlink
:=TLabel
.Create(PuTTYPage
);
538 with LblPlink
do begin
539 Parent
:=PuTTYPage
.Surface
;
541 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
542 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
543 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
544 'variables will be adjusted to point to the following executable:';
550 EdtPlink
:=TEdit
.Create(PuTTYPage
);
551 with EdtPlink
do begin
552 Parent
:=PuTTYPage
.Surface
;
553 Text:=GetPuTTYLocation
;
554 if not FileExists(Text) then begin
562 BtnPlink
:=TButton
.Create(PuTTYPage
);
563 with BtnPlink
do begin
564 Parent
:=PuTTYPage
.Surface
;
566 OnClick
:=@BrowseForPuTTYFolder
;
573 // Restore the setting chosen during a previous install
.
574 Data
:=GetPreviousData('SSH Option','OpenSSH');
575 if Data
='OpenSSH' then begin
576 RdbSSH
[GS_OpenSSH
].Checked
:=True;
577 end else if Data
='Plink' then begin
578 RdbSSH
[GS_Plink
].Checked
:=True;
585 * Create a custom page for the core.autocrlf setting.
588 CRLFPage
:=CreateCustomPage(
590 'Configuring the line ending conversions',
591 'How should Git treat line endings in text files?'
593 PrevPageID
:=CRLFPage
.ID
;
596 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
597 with RdbCRLF
[GC_CRLFAlways
] do begin
598 Parent
:=CRLFPage
.Surface
;
599 Caption
:='Checkout Windows-style, commit Unix-style line endings';
604 Font
.Style
:=[fsBold
];
608 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
609 with LblCRLFAlways
do begin
610 Parent
:=CRLFPage
.Surface
;
612 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
613 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
614 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
622 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
623 with RdbCRLF
[GC_LFOnly
] do begin
624 Parent
:=CRLFPage
.Surface
;
625 Caption
:='Checkout as-is, commit Unix-style line endings';
630 Font
.Style
:=[fsBold
];
634 LblLFOnly
:=TLabel
.Create(CRLFPage
);
635 with LblLFOnly
do begin
636 Parent
:=CRLFPage
.Surface
;
638 'Git will not perform any conversion when checking out text files. When' + #
13 +
639 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
640 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
648 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
649 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
650 Parent
:=CRLFPage
.Surface
;
651 Caption
:='Checkout as-is, commit as-is';
656 Font
.Style
:=[fsBold
];
660 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
661 with LblCRLFCommitAsIs
do begin
662 Parent
:=CRLFPage
.Surface
;
664 'Git will not perform any conversions when checking out or committing' + #
13 +
665 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
666 'projects ("core.autocrlf" is set to "false").';
673 // Restore the setting chosen during a previous install
.
674 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
675 if Data
='LFOnly' then begin
676 RdbCRLF
[GC_LFOnly
].Checked
:=True;
677 end else if Data
='CRLFAlways' then begin
678 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
679 end else if Data
='CRLFCommitAsIs' then begin
680 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
684 * Create a custom page for finding the processes that lock a module.
687 ProcessesPage
:=CreateCustomPage(
689 'Replacing in-use files',
690 'The following applications use files that need to be replaced, please close them.'
693 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
694 with ProcessesListBox
do begin
695 Parent
:=ProcessesPage
.Surface
;
696 Width
:=ProcessesPage
.SurfaceWidth
;
697 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
700 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
701 with ProcessesRefresh
do begin
703 Width
:=WizardForm
.CancelButton
.Width
;
704 Height
:=WizardForm
.CancelButton
.Height
;
705 Top
:=WizardForm
.CancelButton
.Top
;
706 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
708 OnClick
:=@RefreshProcessList
;
711 // This button
is only used by the uninstaller
.
714 // Initially hide the Refresh button
, show it when the process page becomes current
.
715 ProcessesRefresh
.Hide
;
718 function ShouldSkipPage(PageID
:Integer):Boolean;
720 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
721 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
722 RefreshProcessList(NIL);
723 Result
:=(GetArrayLength(Processes
)=0);
729 procedure CurPageChanged(CurPageID
:Integer);
731 if CurPageID
=wpSelectDir
then begin
732 if not IsDirWritable(WizardDirValue
) then begin
733 // If the default directory
is not writable
, choose another default that most likely
is.
734 // This will be checked later again when the user clicks
"Next".
735 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
739 // Show the
"Refresh" button only on the processes page
.
740 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
741 ProcessesRefresh
.Show
;
743 ProcessesRefresh
.Hide
;
747 function NextButtonClick(CurPageID
:Integer):Boolean;
750 Version
:TWindowsVersion
;
754 if CurPageID
=wpSelectDir
then begin
755 if not IsDirWritable(WizardDirValue
) then begin
757 'The specified installation directory does not seem to be writable. ' +
758 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
767 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
768 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
769 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
770 if not Result
then begin
771 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
773 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
774 // It would have been nicer
to just disable the
"Next" button
, but the
775 // WizardForm
exports the button just
read-only
.
776 for i
:=0 to GetArrayLength(Processes
)-1 do begin
777 if not Processes
[i
].Restartable
then begin
778 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
784 Result
:=(GetArrayLength(Processes
)=0);
786 if not Result
then begin
787 GetWindowsVersionEx(Version
);
788 if Version
.Major
>=6 then begin
790 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
791 'Are you sure you want to continue?',
797 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
798 'Are you sure you want to continue anyway?',
807 procedure CurStepChanged(CurStep
:TSetupStep
);
809 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
810 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
815 Version
:TWindowsVersion
;
817 if CurStep
=ssInstall
then begin
818 // Shutdown locking processes just before the actual installation starts
.
819 if SessionHandle
>0 then try
820 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
822 Log('Line {#__LINE__}: RmShutdown not supported.');
828 // Make sure the code below
is only executed just after the actual installation finishes
.
829 if CurStep
<>ssPostInstall
then begin
833 AppDir
:=ExpandConstant('{app}');
836 Bind the imported function addresses
840 DllPath
:=ExpandConstant('{app}\bin;{sys}');
842 // Load the list
of images from a
text file.
843 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
844 if LoadStringsFromFile(FileName
,ImageNames
) then begin
845 Count
:=GetArrayLength(ImageNames
)-1;
846 for i
:=0 to Count
do begin
847 FileName
:=AppDir
+'\'+ImageNames[i];
848 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
849 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
854 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
861 // Load the built-ins from a text file.
862 FileName:=AppDir+'\
{#APP_BUILTINS}';
863 if LoadStringsFromFile(FileName,BuiltIns) then begin
864 Count:=GetArrayLength(BuiltIns)-1;
866 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
867 for i:=0 to Count do begin
868 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
869 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
870 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
874 // Create built
-ins
as aliases
for git
.exe
.
875 for i
:=0 to Count
do begin
876 FileName
:=AppDir
+'\'+BuiltIns[i];
878 // Delete any existing built-in.
879 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
880 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
885 // This will throw an exception on pre-Win2k systems.
886 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
889 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
892 if not LinkCreated then begin
893 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
894 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
895 // This is not a critical error, Git could basically be used without the
896 // aliases for built-ins, so we continue.
901 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
902 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
904 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
905 FileName:=AppDir+'\bin
\'+FindRec
.name
;
906 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
907 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
910 until not FindNext(FindRec
);
914 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
915 MsgBox(Msg
,mbError
,MB_OK
);
917 // This
is not a critical error
, Git could basically be used without the
918 // aliases
for built
-ins
, so we continue
.
925 if RdbCRLF
[GC_LFOnly
].checked
then begin
926 Cmd
:='core.autocrlf input';
927 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
928 Cmd
:='core.autocrlf true';
930 Cmd
:='core.autocrlf false';
932 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
933 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
934 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
935 MsgBox(Msg
,mbError
,MB_OK
);
937 // This
is not a critical error
, the user can probably fix it manually
,
942 Modify the environment
944 This must happen no later than ssPostInstall to make
945 "ChangesEnvironment=yes" not happend before the change!
948 FileName
:=AppDir
+'\setup.ini';
950 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
951 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
952 if (GetArrayLength(EnvSSH
)=1) and
953 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
954 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
955 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
956 MsgBox(Msg
,mbError
,MB_OK
);
958 // This
is not a critical error
, the user can probably fix it manually
,
963 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
964 if (GetArrayLength(EnvSSH
)=1) and
965 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
966 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
967 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
968 MsgBox(Msg
,mbError
,MB_OK
);
970 // This
is not a critical error
, the user can probably fix it manually
,
975 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
976 SetArrayLength(EnvSSH
,1);
977 EnvSSH
[0]:=EdtPlink
.Text;
979 // Set GIT_SSH
as specified by the user
.
980 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
981 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
982 MsgBox(Msg
,mbError
,MB_OK
);
984 // This
is not a critical error
, the user can probably fix it manually
,
988 // Mark that we have changed GIT_SSH by writing its value
to a
file.
989 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
990 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
991 MsgBox(Msg
,mbError
,MB_OK
);
993 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
997 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
998 Msg
:='Line {#__LINE__}: Unable to set the SVN_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 SVN_SSH by writing its value
to a
file.
1006 if not SetIniString('Environment','SVN_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
,
1015 // Get the current user
's directories in PATH.
1016 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1018 // First, remove the installation directory from PATH in any case.
1019 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1020 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1025 // Delete HOME if a previous installation modified it.
1026 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1027 if (GetArrayLength(EnvHome)=1) and
1028 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1029 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1030 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1031 MsgBox(Msg,mbError,MB_OK);
1033 // This is not a critical error, the user can probably fix it manually,
1038 // Modify the PATH variable as requested by the user.
1039 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1040 i:=GetArrayLength(EnvPath);
1041 SetArrayLength(EnvPath,i+1);
1043 // List \cmd before \bin so \cmd has higher priority and programs in
1044 // there will be called in favor of those in \bin.
1045 EnvPath[i]:=AppDir+'\cmd
';
1047 if RdbPath[GP_CmdTools].Checked then begin
1048 SetArrayLength(EnvPath,i+2);
1049 EnvPath[i+1]:=AppDir+'\bin
';
1051 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1052 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1053 i:=GetArrayLength(EnvHome);
1054 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1055 SetArrayLength(EnvHome,1);
1056 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1057 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1058 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1059 MsgBox(Msg,mbError,MB_OK);
1061 // This is not a critical error, the user can probably fix it manually,
1065 // Mark that we have changed HOME.
1066 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1067 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1068 MsgBox(Msg,mbError,MB_OK);
1070 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1077 // Set the current user's PATH directories
.
1078 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1079 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1080 MsgBox(Msg
,mbError
,MB_OK
);
1082 // This
is not a critical error
, the user can probably fix it manually
,
1087 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1090 GetWindowsVersionEx(Version
);
1091 if Version
.Major
<6 then begin
1092 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1093 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1095 Cmd
:=AppDir
+'\bin\sh.exe';
1096 TempName
:='--login -i';
1098 FileName
:=AppDir
+'\etc\git.ico';
1100 if IsComponentSelected('icons\quicklaunch') then begin
1102 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1106 , '%HOMEDRIVE%%HOMEPATH%'
1112 if IsComponentSelected('icons\desktop') then begin
1114 GetShellFolder('desktop')+'\Git Bash.lnk'
1118 , '%HOMEDRIVE%%HOMEPATH%'
1125 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1126 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1127 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1129 AppDir
+'\Git Bash.lnk'
1140 Create the Windows Explorer integrations
1143 if IsAdminLoggedOn
then begin
1144 RootKey
:=HKEY_LOCAL_MACHINE
;
1146 RootKey
:=HKEY_CURRENT_USER
;
1149 if IsComponentSelected('ext\reg\shellhere') then begin
1150 Msg
:='Git Ba&sh Here';
1151 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1152 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1153 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1154 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1155 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1156 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then begin
1157 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1158 MsgBox(Msg
,mbError
,MB_OK
);
1160 // This
is not a critical error
, the user can probably fix it manually
,
1165 if IsComponentSelected('ext\reg\guihere') then begin
1166 Msg
:='Git &GUI Here';
1167 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1168 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1169 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1170 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1171 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1172 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
)) then begin
1173 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1174 MsgBox(Msg
,mbError
,MB_OK
);
1176 // This
is not a critical error
, the user can probably fix it manually
,
1181 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1182 if IsComponentSelected('ext\cheetah') then begin
1183 DeleteContextMenuEntries
;
1185 if isWin64
then begin
1186 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1188 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1190 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1191 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1196 Restart any processes that were shut down via the Restart Manager
1199 if SessionHandle
>0 then try
1200 RmRestart(SessionHandle
,0,0);
1201 RmEndSession(SessionHandle
);
1203 Log('Line {#__LINE__}: RmRestart not supported.');
1207 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1211 // Git Path options
.
1213 if RdbPath
[GP_BashOnly
].Checked
then begin
1215 end else if RdbPath
[GP_Cmd
].Checked
then begin
1217 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1220 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1224 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1226 end else if RdbSSH
[GS_Plink
].Checked
then begin
1229 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1231 // Line ending conversion options
.
1233 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1235 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1237 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1238 Data
:='CRLFCommitAsIs';
1240 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1247 function InitializeUninstall
:Boolean;
1251 ExitButton
,RefreshButton
:TButton
;
1255 Form
:=CreateCustomForm
;
1257 Form
.Caption
:='Git Uninstall: Removing in-use files';
1258 Form
.ClientWidth
:=ScaleX(500);
1259 Form
.ClientHeight
:=ScaleY(256);
1262 Info
:=TLabel
.Create(Form
);
1268 Caption
:='The following applications use files that need to be removed, please close them.';
1271 ContinueButton
:=TButton
.Create(Form
);
1272 with ContinueButton
do begin
1274 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1275 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1278 Caption
:='Continue';
1282 ExitButton
:=TButton
.Create(Form
);
1283 with ExitButton
do begin
1285 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1286 Top
:=ContinueButton
.Top
;
1290 ModalResult
:=mrCancel
;
1294 RefreshButton
:=TButton
.Create(Form
);
1295 with RefreshButton
do begin
1298 Top
:=ExitButton
.Top
;
1302 OnClick
:=@RefreshProcessList
;
1305 ProcessesListBox
:=TListBox
.Create(Form
);
1306 with ProcessesListBox
do begin
1309 Top
:=Info
.Top
+Info
.Height
+11;
1310 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1311 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1314 Form
.ActiveControl
:=ContinueButton
;
1316 RefreshProcessList(NIL);
1317 if GetArrayLength(Processes
)>0 then begin
1318 // Now that these dialogs are going
to be shown
, we should probably
1319 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1320 // unfortunately that
is not possible
with Inno Setup currently
.
1321 Result
:=(Form
.ShowModal()=mrOk
);
1323 // Note
: The number
of processes might have changed during a refresh
.
1324 if Result
and (GetArrayLength(Processes
)>0) then begin
1326 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1327 'Are you sure you want to continue anyway?',
1340 // Even though the name
of this
function suggests otherwise most
of the
1341 // code below
is only executed right before the actual uninstallation
.
1342 // This happens because
of the
if-guard right
in the beginning
of this
1344 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1346 AppDir
,FileName
,Msg
:String;
1347 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1350 if CurUninstallStep
<>usUninstall
then begin
1354 // Reset the console
font (the FontType
is reset
in the Registry section
).
1355 if IsComponentInstalled('consolefont') then begin
1356 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1357 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1358 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1359 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1364 Modify the environment
1366 This must happen no later than usUninstall to make
1367 "ChangesEnvironment=yes" not happend before the change!
1370 AppDir
:=ExpandConstant('{app}');
1371 FileName
:=AppDir
+'\setup.ini';
1373 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1374 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1375 if (GetArrayLength(EnvSSH)=1) and
1376 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1377 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1378 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1379 MsgBox(Msg,mbError,MB_OK);
1381 // This is not a critical error, the user can probably fix it manually,
1386 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1387 if (GetArrayLength(EnvSSH)=1) and
1388 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1389 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1390 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1391 MsgBox(Msg,mbError,MB_OK);
1393 // This is not a critical error, the user can probably fix it manually,
1398 // Get the current user's directories
in PATH
.
1399 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1401 // Remove the installation directory from PATH
in any
case, even
if it
1402 // was
not added by the installer
.
1403 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1404 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1409 // Reset the current user
's directories in PATH.
1410 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1411 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1412 MsgBox(Msg,mbError,MB_OK);
1414 // This is not a critical error, the user can probably fix it manually,
1418 // Reset the current user's HOME
if we modified it
.
1419 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1420 if (GetArrayLength(EnvHome
)=1) and
1421 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1422 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1423 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1424 MsgBox(Msg
,mbError
,MB_OK
);
1426 // This
is not a critical error
, the user can probably fix it manually
,
1431 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1432 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1433 MsgBox(Msg
,mbError
,MB_OK
);
1435 // This
is not a critical error
, the user can probably fix it manually
,
1440 Delete the Windows Explorer integrations
1443 DeleteContextMenuEntries
;
1445 if isWin64
then begin
1446 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1448 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1450 if FileExists(FileName
) then begin
1451 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1452 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1453 MsgBox(Msg
,mbError
,MB_OK
);
1457 if not DeleteFile(FileName
) then begin
1458 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1459 MsgBox(Msg
,mbError
,MB_OK
);