1 ; Uncomment the line below to be able to compile the script from within the IDE.
2 ;#define COMPILE_FROM_IDE
5 #ifdef COMPILE_FROM_IDE
6 #define APP_VERSION
'Snapshot'
8 #define APP_VERSION
'%APPVERSION%'
10 #define APP_URL
'http://msysgit.googlecode.com/'
11 #define APP_BUILTINS
'etc\fileList-builtins.txt'
12 #define APP_BINDIMAGE
'etc\fileList-bindimage.txt'
14 #define PLINK_PATH_ERROR_MSG
'Please enter a valid path to a version of Plink.'
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
);
251 'Please select the Plink executable:',
253 ExtractFilePath(EdtPlink
.Text),
254 'Executable Files|*.exe',
257 if Pos('plink',LowerCase(Name
))>0 then begin
259 RdbSSH
[GS_Plink
].Checked
:=True;
261 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
265 procedure DeleteContextMenuEntries
;
267 AppDir
,Command
,Msg
:String;
271 AppDir
:=ExpandConstant('{app}');
273 if IsAdminLoggedOn
then begin
274 RootKey
:=HKEY_LOCAL_MACHINE
;
276 RootKey
:=HKEY_CURRENT_USER
;
279 SetArrayLength(Keys
,4);
280 Keys
[0]:='SOFTWARE\Classes\Directory\shell\git_shell';
281 Keys
[1]:='SOFTWARE\Classes\Directory\Background\shell\git_shell';
282 Keys
[2]:='SOFTWARE\Classes\Directory\shell\git_gui';
283 Keys
[3]:='SOFTWARE\Classes\Directory\Background\shell\git_gui';
285 for i
:=0 to Length(Keys
)-1 do begin
287 RegQueryStringValue(RootKey
,Keys
[i
]+'\command','',Command
);
288 if Pos(AppDir
,Command
)>0 then begin
289 if not RegDeleteKeyIncludingSubkeys(RootKey
,Keys
[i
]) then begin
290 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash / GUI Here" shell extension.';
291 MsgBox(Msg
,mbError
,MB_OK
);
293 // This
is not a critical error
, the user can probably fix it manually
,
300 procedure RefreshProcessList(Sender
:TObject
);
302 Version
:TWindowsVersion
;
303 Modules
:TArrayOfString
;
304 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
307 ManualClosingRequired
:Boolean;
309 GetWindowsVersionEx(Version
);
311 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
312 if Version
.Major
>=6 then begin
313 SetArrayLength(Modules
,5);
314 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
315 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
316 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
317 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
318 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
319 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
321 SetArrayLength(Modules
,3);
322 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
323 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
324 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
325 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
327 SetArrayLength(Modules
,2);
328 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
329 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
330 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
332 // Misuse the
"Restartable" flag
to indicate which processes are required
333 // to be closed before setup can continue
, and which just should be closed
334 // in order
to make changes take effect immediately
.
335 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
336 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
337 Processes
[i
]:=ProcsCloseRequired
[i
];
338 Processes
[i
].Restartable
:=False;
340 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
341 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
342 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
346 ManualClosingRequired
:=False;
348 ProcessesListBox
.Items
.Clear
;
349 if (Sender
=NIL) or (SessionHandle
>0) then begin
350 for i
:=0 to GetArrayLength(Processes
)-1 do begin
351 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
352 if Processes
[i
].Restartable
then begin
353 Caption
:=Caption
+', closing is optional';
355 Caption
:=Caption
+', closing is required';
356 ManualClosingRequired
:=True;
358 Caption
:=Caption
+')';
359 ProcessesListBox
.Items
.Append(Caption
);
363 if ContinueButton
<>NIL then begin
364 ContinueButton
.Enabled
:=not ManualClosingRequired
;
372 procedure InitializeWizard
;
375 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
376 LblOpenSSH
,LblPlink
:TLabel
;
377 PuTTYSessions
:TArrayOfString
;
378 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
383 PrevPageID
:=wpSelectProgramGroup
;
386 * Create a custom page for modifying the environment.
389 PathPage
:=CreateCustomPage(
391 'Adjusting your PATH environment',
392 'How would you like to use Git from the command line?'
394 PrevPageID
:=PathPage
.ID
;
397 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
398 with RdbPath
[GP_BashOnly
] do begin
399 Parent
:=PathPage
.Surface
;
400 Caption
:='Use Git Bash only';
405 Font
.Style
:=[fsBold
];
409 LblGitBash
:=TLabel
.Create(PathPage
);
410 with LblGitBash
do begin
411 Parent
:=PathPage
.Surface
;
413 'This is the most conservative choice if you are concerned about the stability' + #
13 +
414 'of your system. Your PATH will not be modified.';
422 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
423 with RdbPath
[GP_Cmd
] do begin
424 Parent
:=PathPage
.Surface
;
425 Caption
:='Run Git from the Windows Command Prompt';
430 Font
.Style
:=[fsBold
];
433 LblGitCmd
:=TLabel
.Create(PathPage
);
434 with LblGitCmd
do begin
435 Parent
:=PathPage
.Surface
;
437 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
438 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
439 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
447 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
448 with RdbPath
[GP_CmdTools
] do begin
449 Parent
:=PathPage
.Surface
;
450 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
455 Font
.Style
:=[fsBold
];
458 LblGitCmdTools
:=TLabel
.Create(PathPage
);
459 with LblGitCmdTools
do begin
460 Parent
:=PathPage
.Surface
;
461 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
467 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
468 with LblGitCmdToolsWarn
do begin
469 Parent
:=PathPage
.Surface
;
471 'Warning: This will override Windows tools like find.exe and' + #
13 +
472 'sort.exe. Select this option only if you understand the implications.';
478 Font
.Style
:=[fsBold
];
481 // Restore the setting chosen during a previous install
.
482 Data
:=GetPreviousData('Path Option','BashOnly');
483 if Data
='BashOnly' then begin
484 RdbPath
[GP_BashOnly
].Checked
:=True;
485 end else if Data
='Cmd' then begin
486 RdbPath
[GP_Cmd
].Checked
:=True;
487 end else if Data
='CmdTools' then begin
488 RdbPath
[GP_CmdTools
].Checked
:=True;
492 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
493 * if at least one PuTTY session is found in the Registry.
496 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
497 PuTTYPage
:=CreateCustomPage(
499 'Choosing the SSH executable',
500 'Which Secure Shell client program would you like Git to use?'
502 PrevPageID
:=PuTTYPage
.ID
;
505 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
506 with RdbSSH
[GS_OpenSSH
] do begin
507 Parent
:=PuTTYPage
.Surface
;
508 Caption
:='Use OpenSSH';
513 Font
.Style
:=[fsBold
];
517 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
518 with LblOpenSSH
do begin
519 Parent
:=PuTTYPage
.Surface
;
521 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
522 'environment variables will not be modified.';
530 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
531 with RdbSSH
[GS_Plink
] do begin
532 Parent
:=PuTTYPage
.Surface
;
533 Caption
:='Use (Tortoise)Plink';
538 Font
.Style
:=[fsBold
];
541 LblPlink
:=TLabel
.Create(PuTTYPage
);
542 with LblPlink
do begin
543 Parent
:=PuTTYPage
.Surface
;
545 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
546 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
547 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
548 'variables will be adjusted to point to the following executable:';
554 EdtPlink
:=TEdit
.Create(PuTTYPage
);
555 with EdtPlink
do begin
556 Parent
:=PuTTYPage
.Surface
;
557 Text:=GetPreviousData('Plink Path','');
558 if not FileExists(Text) then begin
559 Text:=GuessPlinkExecutable
;
561 if not FileExists(Text) then begin
569 BtnPlink
:=TButton
.Create(PuTTYPage
);
570 with BtnPlink
do begin
571 Parent
:=PuTTYPage
.Surface
;
573 OnClick
:=@BrowseForPuTTYFolder
;
580 // Restore the setting chosen during a previous install
.
581 Data
:=GetPreviousData('SSH Option','OpenSSH');
582 if Data
='OpenSSH' then begin
583 RdbSSH
[GS_OpenSSH
].Checked
:=True;
584 end else if Data
='Plink' then begin
585 RdbSSH
[GS_Plink
].Checked
:=True;
592 * Create a custom page for the core.autocrlf setting.
595 CRLFPage
:=CreateCustomPage(
597 'Configuring the line ending conversions',
598 'How should Git treat line endings in text files?'
600 PrevPageID
:=CRLFPage
.ID
;
603 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
604 with RdbCRLF
[GC_CRLFAlways
] do begin
605 Parent
:=CRLFPage
.Surface
;
606 Caption
:='Checkout Windows-style, commit Unix-style line endings';
611 Font
.Style
:=[fsBold
];
615 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
616 with LblCRLFAlways
do begin
617 Parent
:=CRLFPage
.Surface
;
619 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
620 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
621 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
629 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
630 with RdbCRLF
[GC_LFOnly
] do begin
631 Parent
:=CRLFPage
.Surface
;
632 Caption
:='Checkout as-is, commit Unix-style line endings';
637 Font
.Style
:=[fsBold
];
641 LblLFOnly
:=TLabel
.Create(CRLFPage
);
642 with LblLFOnly
do begin
643 Parent
:=CRLFPage
.Surface
;
645 'Git will not perform any conversion when checking out text files. When' + #
13 +
646 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
647 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
655 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
656 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
657 Parent
:=CRLFPage
.Surface
;
658 Caption
:='Checkout as-is, commit as-is';
663 Font
.Style
:=[fsBold
];
667 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
668 with LblCRLFCommitAsIs
do begin
669 Parent
:=CRLFPage
.Surface
;
671 'Git will not perform any conversions when checking out or committing' + #
13 +
672 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
673 'projects ("core.autocrlf" is set to "false").';
680 // Restore the setting chosen during a previous install
.
681 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
682 if Data
='LFOnly' then begin
683 RdbCRLF
[GC_LFOnly
].Checked
:=True;
684 end else if Data
='CRLFAlways' then begin
685 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
686 end else if Data
='CRLFCommitAsIs' then begin
687 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
691 * Create a custom page for finding the processes that lock a module.
694 ProcessesPage
:=CreateCustomPage(
696 'Replacing in-use files',
697 'The following applications use files that need to be replaced, please close them.'
700 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
701 with ProcessesListBox
do begin
702 Parent
:=ProcessesPage
.Surface
;
703 Width
:=ProcessesPage
.SurfaceWidth
;
704 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
707 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
708 with ProcessesRefresh
do begin
710 Width
:=WizardForm
.CancelButton
.Width
;
711 Height
:=WizardForm
.CancelButton
.Height
;
712 Top
:=WizardForm
.CancelButton
.Top
;
713 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
715 OnClick
:=@RefreshProcessList
;
718 // This button
is only used by the uninstaller
.
721 // Initially hide the Refresh button
, show it when the process page becomes current
.
722 ProcessesRefresh
.Hide
;
725 function ShouldSkipPage(PageID
:Integer):Boolean;
727 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
728 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
729 RefreshProcessList(NIL);
730 Result
:=(GetArrayLength(Processes
)=0);
736 procedure CurPageChanged(CurPageID
:Integer);
738 if CurPageID
=wpInfoBefore
then begin
739 if WizardForm
.NextButton
.Enabled
then begin
740 // By default
, do not show a blinking cursor
for InfoBeforeFile
.
741 WizardForm
.ActiveControl
:=WizardForm
.NextButton
;
743 end else if CurPageID
=wpSelectDir
then begin
744 if not IsDirWritable(WizardDirValue
) then begin
745 // If the default directory
is not writable
, choose another default that most likely
is.
746 // This will be checked later again when the user clicks
"Next".
747 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
749 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
750 // Show the
"Refresh" button only on the processes page
.
751 ProcessesRefresh
.Show
;
753 ProcessesRefresh
.Hide
;
757 function NextButtonClick(CurPageID
:Integer):Boolean;
760 Version
:TWindowsVersion
;
764 if CurPageID
=wpSelectDir
then begin
765 if not IsDirWritable(WizardDirValue
) then begin
767 'The specified installation directory does not seem to be writable. ' +
768 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
777 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
778 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
779 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
780 if not Result
then begin
781 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
783 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
784 // It would have been nicer
to just disable the
"Next" button
, but the
785 // WizardForm
exports the button just
read-only
.
786 for i
:=0 to GetArrayLength(Processes
)-1 do begin
787 if not Processes
[i
].Restartable
then begin
788 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
794 Result
:=(GetArrayLength(Processes
)=0);
796 if not Result
then begin
797 GetWindowsVersionEx(Version
);
798 if Version
.Major
>=6 then begin
800 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
801 'Are you sure you want to continue?',
807 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
808 'Are you sure you want to continue anyway?',
817 procedure CurStepChanged(CurStep
:TSetupStep
);
819 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
820 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
825 Version
:TWindowsVersion
;
827 if CurStep
=ssInstall
then begin
828 // Shutdown locking processes just before the actual installation starts
.
829 if SessionHandle
>0 then try
830 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
832 Log('Line {#__LINE__}: RmShutdown not supported.');
838 // Make sure the code below
is only executed just after the actual installation finishes
.
839 if CurStep
<>ssPostInstall
then begin
843 AppDir
:=ExpandConstant('{app}');
846 Bind the imported function addresses
850 DllPath
:=ExpandConstant('{app}\bin;{sys}');
852 // Load the list
of images from a
text file.
853 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
854 if LoadStringsFromFile(FileName
,ImageNames
) then begin
855 Count
:=GetArrayLength(ImageNames
)-1;
856 for i
:=0 to Count
do begin
857 FileName
:=AppDir
+'\'+ImageNames[i];
858 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
859 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
864 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
871 // Load the built-ins from a text file.
872 FileName:=AppDir+'\
{#APP_BUILTINS}';
873 if LoadStringsFromFile(FileName,BuiltIns) then begin
874 Count:=GetArrayLength(BuiltIns)-1;
876 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
877 for i:=0 to Count do begin
878 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
879 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
880 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
884 // Create built
-ins
as aliases
for git
.exe
.
885 for i
:=0 to Count
do begin
886 FileName
:=AppDir
+'\'+BuiltIns[i];
888 // Delete any existing built-in.
889 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
890 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
895 // This will throw an exception on pre-Win2k systems.
896 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
899 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
902 if not LinkCreated then begin
903 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
904 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
905 // This is not a critical error, Git could basically be used without the
906 // aliases for built-ins, so we continue.
911 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
912 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
914 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
915 FileName:=AppDir+'\bin
\'+FindRec
.name
;
916 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
917 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
920 until not FindNext(FindRec
);
924 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
925 MsgBox(Msg
,mbError
,MB_OK
);
927 // This
is not a critical error
, Git could basically be used without the
928 // aliases
for built
-ins
, so we continue
.
935 if RdbCRLF
[GC_LFOnly
].checked
then begin
936 Cmd
:='core.autocrlf input';
937 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
938 Cmd
:='core.autocrlf true';
940 Cmd
:='core.autocrlf false';
942 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
943 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
944 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
945 MsgBox(Msg
,mbError
,MB_OK
);
947 // This
is not a critical error
, the user can probably fix it manually
,
952 Modify the environment
954 This must happen no later than ssPostInstall to make
955 "ChangesEnvironment=yes" not happend before the change!
958 FileName
:=AppDir
+'\setup.ini';
960 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
961 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
962 if (GetArrayLength(EnvSSH
)=1) and
963 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
964 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
965 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
966 MsgBox(Msg
,mbError
,MB_OK
);
968 // This
is not a critical error
, the user can probably fix it manually
,
973 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
974 if (GetArrayLength(EnvSSH
)=1) and
975 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
976 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
977 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
978 MsgBox(Msg
,mbError
,MB_OK
);
980 // This
is not a critical error
, the user can probably fix it manually
,
985 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
986 SetArrayLength(EnvSSH
,1);
987 EnvSSH
[0]:=EdtPlink
.Text;
989 // Set GIT_SSH
as specified by the user
.
990 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
991 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
992 MsgBox(Msg
,mbError
,MB_OK
);
994 // This
is not a critical error
, the user can probably fix it manually
,
998 // Mark that we have changed GIT_SSH by writing its value
to a
file.
999 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
1000 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1001 MsgBox(Msg
,mbError
,MB_OK
);
1003 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1007 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
1008 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
1009 MsgBox(Msg
,mbError
,MB_OK
);
1011 // This
is not a critical error
, the user can probably fix it manually
,
1015 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1016 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1017 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1018 MsgBox(Msg
,mbError
,MB_OK
);
1020 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1025 // Get the current user
's directories in PATH.
1026 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1028 // First, remove the installation directory from PATH in any case.
1029 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1030 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1035 // Delete HOME if a previous installation modified it.
1036 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1037 if (GetArrayLength(EnvHome)=1) and
1038 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1039 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1040 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1041 MsgBox(Msg,mbError,MB_OK);
1043 // This is not a critical error, the user can probably fix it manually,
1048 // Modify the PATH variable as requested by the user.
1049 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1050 i:=GetArrayLength(EnvPath);
1051 SetArrayLength(EnvPath,i+1);
1053 // List \cmd before \bin so \cmd has higher priority and programs in
1054 // there will be called in favor of those in \bin.
1055 EnvPath[i]:=AppDir+'\cmd
';
1057 if RdbPath[GP_CmdTools].Checked then begin
1058 SetArrayLength(EnvPath,i+2);
1059 EnvPath[i+1]:=AppDir+'\bin
';
1061 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1062 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1063 i:=GetArrayLength(EnvHome);
1064 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1065 SetArrayLength(EnvHome,1);
1066 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1067 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1068 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1069 MsgBox(Msg,mbError,MB_OK);
1071 // This is not a critical error, the user can probably fix it manually,
1075 // Mark that we have changed HOME.
1076 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1077 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1078 MsgBox(Msg,mbError,MB_OK);
1080 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1087 // Set the current user's PATH directories
.
1088 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1089 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1090 MsgBox(Msg
,mbError
,MB_OK
);
1092 // This
is not a critical error
, the user can probably fix it manually
,
1097 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1100 GetWindowsVersionEx(Version
);
1101 if Version
.Major
<6 then begin
1102 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1103 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1105 Cmd
:=AppDir
+'\bin\sh.exe';
1106 TempName
:='--login -i';
1108 FileName
:=AppDir
+'\etc\git.ico';
1110 if IsComponentSelected('icons\quicklaunch') then begin
1112 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1116 , '%HOMEDRIVE%%HOMEPATH%'
1122 if IsComponentSelected('icons\desktop') then begin
1124 GetShellFolder('desktop')+'\Git Bash.lnk'
1128 , '%HOMEDRIVE%%HOMEPATH%'
1135 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1136 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1137 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1139 AppDir
+'\Git Bash.lnk'
1150 Create the Windows Explorer integrations
1153 if IsAdminLoggedOn
then begin
1154 RootKey
:=HKEY_LOCAL_MACHINE
;
1156 RootKey
:=HKEY_CURRENT_USER
;
1159 if IsComponentSelected('ext\reg\shellhere') then begin
1160 Msg
:='Git Ba&sh Here';
1161 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1162 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1163 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1164 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1165 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1166 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then begin
1167 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1168 MsgBox(Msg
,mbError
,MB_OK
);
1170 // This
is not a critical error
, the user can probably fix it manually
,
1175 if IsComponentSelected('ext\reg\guihere') then begin
1176 Msg
:='Git &GUI Here';
1177 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1178 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1179 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1180 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1181 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1182 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
)) then begin
1183 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1184 MsgBox(Msg
,mbError
,MB_OK
);
1186 // This
is not a critical error
, the user can probably fix it manually
,
1191 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1192 if IsComponentSelected('ext\cheetah') then begin
1193 DeleteContextMenuEntries
;
1195 if isWin64
then begin
1196 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1198 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1200 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1201 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1206 Restart any processes that were shut down via the Restart Manager
1209 if SessionHandle
>0 then try
1210 RmRestart(SessionHandle
,0,0);
1211 RmEndSession(SessionHandle
);
1213 Log('Line {#__LINE__}: RmRestart not supported.');
1217 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1221 // Git Path options
.
1223 if RdbPath
[GP_BashOnly
].Checked
then begin
1225 end else if RdbPath
[GP_Cmd
].Checked
then begin
1227 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1230 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1234 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1236 end else if RdbSSH
[GS_Plink
].Checked
then begin
1238 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1240 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1242 // Line ending conversion options
.
1244 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1246 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1248 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1249 Data
:='CRLFCommitAsIs';
1251 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1258 function InitializeUninstall
:Boolean;
1262 ExitButton
,RefreshButton
:TButton
;
1266 Form
:=CreateCustomForm
;
1268 Form
.Caption
:='Git Uninstall: Removing in-use files';
1269 Form
.ClientWidth
:=ScaleX(500);
1270 Form
.ClientHeight
:=ScaleY(256);
1273 Info
:=TLabel
.Create(Form
);
1279 Caption
:='The following applications use files that need to be removed, please close them.';
1282 ContinueButton
:=TButton
.Create(Form
);
1283 with ContinueButton
do begin
1285 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1286 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1289 Caption
:='Continue';
1293 ExitButton
:=TButton
.Create(Form
);
1294 with ExitButton
do begin
1296 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1297 Top
:=ContinueButton
.Top
;
1301 ModalResult
:=mrCancel
;
1305 RefreshButton
:=TButton
.Create(Form
);
1306 with RefreshButton
do begin
1309 Top
:=ExitButton
.Top
;
1313 OnClick
:=@RefreshProcessList
;
1316 ProcessesListBox
:=TListBox
.Create(Form
);
1317 with ProcessesListBox
do begin
1320 Top
:=Info
.Top
+Info
.Height
+11;
1321 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1322 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1325 Form
.ActiveControl
:=ContinueButton
;
1327 RefreshProcessList(NIL);
1328 if GetArrayLength(Processes
)>0 then begin
1329 // Now that these dialogs are going
to be shown
, we should probably
1330 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1331 // unfortunately that
is not possible
with Inno Setup currently
.
1332 Result
:=(Form
.ShowModal()=mrOk
);
1334 // Note
: The number
of processes might have changed during a refresh
.
1335 if Result
and (GetArrayLength(Processes
)>0) then begin
1337 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1338 'Are you sure you want to continue anyway?',
1351 // Even though the name
of this
function suggests otherwise most
of the
1352 // code below
is only executed right before the actual uninstallation
.
1353 // This happens because
of the
if-guard right
in the beginning
of this
1355 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1357 AppDir
,FileName
,Msg
:String;
1358 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1361 if CurUninstallStep
<>usUninstall
then begin
1365 // Reset the console
font (the FontType
is reset
in the Registry section
).
1366 if IsComponentInstalled('consolefont') then begin
1367 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1368 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1369 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1370 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1375 Modify the environment
1377 This must happen no later than usUninstall to make
1378 "ChangesEnvironment=yes" not happend before the change!
1381 AppDir
:=ExpandConstant('{app}');
1382 FileName
:=AppDir
+'\setup.ini';
1384 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1385 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1386 if (GetArrayLength(EnvSSH)=1) and
1387 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1388 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1389 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1390 MsgBox(Msg,mbError,MB_OK);
1392 // This is not a critical error, the user can probably fix it manually,
1397 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1398 if (GetArrayLength(EnvSSH)=1) and
1399 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1400 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1401 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1402 MsgBox(Msg,mbError,MB_OK);
1404 // This is not a critical error, the user can probably fix it manually,
1409 // Get the current user's directories
in PATH
.
1410 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1412 // Remove the installation directory from PATH
in any
case, even
if it
1413 // was
not added by the installer
.
1414 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1415 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1420 // Reset the current user
's directories in PATH.
1421 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1422 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1423 MsgBox(Msg,mbError,MB_OK);
1425 // This is not a critical error, the user can probably fix it manually,
1429 // Reset the current user's HOME
if we modified it
.
1430 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1431 if (GetArrayLength(EnvHome
)=1) and
1432 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1433 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1434 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1435 MsgBox(Msg
,mbError
,MB_OK
);
1437 // This
is not a critical error
, the user can probably fix it manually
,
1442 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1443 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1444 MsgBox(Msg
,mbError
,MB_OK
);
1446 // This
is not a critical error
, the user can probably fix it manually
,
1451 Delete the Windows Explorer integrations
1454 DeleteContextMenuEntries
;
1456 if isWin64
then begin
1457 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1459 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1461 if FileExists(FileName
) then begin
1462 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1463 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1464 MsgBox(Msg
,mbError
,MB_OK
);
1468 if not DeleteFile(FileName
) then begin
1469 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1470 MsgBox(Msg
,mbError
,MB_OK
);