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
,EnvSSH
: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
;
558 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
559 if (GetArrayLength(EnvSSH
)=1) and (Pos('plink',LowerCase(EnvSSH
[0]))>0) then begin
562 if not FileExists(Text) then begin
563 Text:=GetPreviousData('Plink Path','');
565 if not FileExists(Text) then begin
566 Text:=GuessPlinkExecutable
;
568 if not FileExists(Text) then begin
577 BtnPlink
:=TButton
.Create(PuTTYPage
);
578 with BtnPlink
do begin
579 Parent
:=PuTTYPage
.Surface
;
581 OnClick
:=@BrowseForPuTTYFolder
;
588 // Restore the setting chosen during a previous install
.
589 Data
:=GetPreviousData('SSH Option','OpenSSH');
590 if Data
='OpenSSH' then begin
591 RdbSSH
[GS_OpenSSH
].Checked
:=True;
592 end else if Data
='Plink' then begin
593 RdbSSH
[GS_Plink
].Checked
:=True;
600 * Create a custom page for the core.autocrlf setting.
603 CRLFPage
:=CreateCustomPage(
605 'Configuring the line ending conversions',
606 'How should Git treat line endings in text files?'
608 PrevPageID
:=CRLFPage
.ID
;
611 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
612 with RdbCRLF
[GC_CRLFAlways
] do begin
613 Parent
:=CRLFPage
.Surface
;
614 Caption
:='Checkout Windows-style, commit Unix-style line endings';
619 Font
.Style
:=[fsBold
];
623 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
624 with LblCRLFAlways
do begin
625 Parent
:=CRLFPage
.Surface
;
627 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
628 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
629 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
637 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
638 with RdbCRLF
[GC_LFOnly
] do begin
639 Parent
:=CRLFPage
.Surface
;
640 Caption
:='Checkout as-is, commit Unix-style line endings';
645 Font
.Style
:=[fsBold
];
649 LblLFOnly
:=TLabel
.Create(CRLFPage
);
650 with LblLFOnly
do begin
651 Parent
:=CRLFPage
.Surface
;
653 'Git will not perform any conversion when checking out text files. When' + #
13 +
654 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
655 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
663 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
664 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
665 Parent
:=CRLFPage
.Surface
;
666 Caption
:='Checkout as-is, commit as-is';
671 Font
.Style
:=[fsBold
];
675 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
676 with LblCRLFCommitAsIs
do begin
677 Parent
:=CRLFPage
.Surface
;
679 'Git will not perform any conversions when checking out or committing' + #
13 +
680 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
681 'projects ("core.autocrlf" is set to "false").';
688 // Restore the setting chosen during a previous install
.
689 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
690 if Data
='LFOnly' then begin
691 RdbCRLF
[GC_LFOnly
].Checked
:=True;
692 end else if Data
='CRLFAlways' then begin
693 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
694 end else if Data
='CRLFCommitAsIs' then begin
695 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
699 * Create a custom page for finding the processes that lock a module.
702 ProcessesPage
:=CreateCustomPage(
704 'Replacing in-use files',
705 'The following applications use files that need to be replaced, please close them.'
708 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
709 with ProcessesListBox
do begin
710 Parent
:=ProcessesPage
.Surface
;
711 Width
:=ProcessesPage
.SurfaceWidth
;
712 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
715 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
716 with ProcessesRefresh
do begin
718 Width
:=WizardForm
.CancelButton
.Width
;
719 Height
:=WizardForm
.CancelButton
.Height
;
720 Top
:=WizardForm
.CancelButton
.Top
;
721 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
723 OnClick
:=@RefreshProcessList
;
726 // This button
is only used by the uninstaller
.
729 // Initially hide the Refresh button
, show it when the process page becomes current
.
730 ProcessesRefresh
.Hide
;
733 function ShouldSkipPage(PageID
:Integer):Boolean;
735 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
736 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
737 RefreshProcessList(NIL);
738 Result
:=(GetArrayLength(Processes
)=0);
744 procedure CurPageChanged(CurPageID
:Integer);
746 if CurPageID
=wpInfoBefore
then begin
747 if WizardForm
.NextButton
.Enabled
then begin
748 // By default
, do not show a blinking cursor
for InfoBeforeFile
.
749 WizardForm
.ActiveControl
:=WizardForm
.NextButton
;
751 end else if CurPageID
=wpSelectDir
then begin
752 if not IsDirWritable(WizardDirValue
) then begin
753 // If the default directory
is not writable
, choose another default that most likely
is.
754 // This will be checked later again when the user clicks
"Next".
755 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
757 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
758 // Show the
"Refresh" button only on the processes page
.
759 ProcessesRefresh
.Show
;
761 ProcessesRefresh
.Hide
;
765 function NextButtonClick(CurPageID
:Integer):Boolean;
768 Version
:TWindowsVersion
;
772 if CurPageID
=wpSelectDir
then begin
773 if not IsDirWritable(WizardDirValue
) then begin
775 'The specified installation directory does not seem to be writable. ' +
776 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
785 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
786 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
787 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
788 if not Result
then begin
789 MsgBox('{#PLINK_PATH_ERROR_MSG}',mbError
,MB_OK
);
791 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
792 // It would have been nicer
to just disable the
"Next" button
, but the
793 // WizardForm
exports the button just
read-only
.
794 for i
:=0 to GetArrayLength(Processes
)-1 do begin
795 if not Processes
[i
].Restartable
then begin
796 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
802 Result
:=(GetArrayLength(Processes
)=0);
804 if not Result
then begin
805 GetWindowsVersionEx(Version
);
806 if Version
.Major
>=6 then begin
808 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
809 'Are you sure you want to continue?',
815 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
816 'Are you sure you want to continue anyway?',
825 procedure CurStepChanged(CurStep
:TSetupStep
);
827 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
828 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
833 Version
:TWindowsVersion
;
835 if CurStep
=ssInstall
then begin
836 // Shutdown locking processes just before the actual installation starts
.
837 if SessionHandle
>0 then try
838 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
840 Log('Line {#__LINE__}: RmShutdown not supported.');
846 // Make sure the code below
is only executed just after the actual installation finishes
.
847 if CurStep
<>ssPostInstall
then begin
851 AppDir
:=ExpandConstant('{app}');
854 Bind the imported function addresses
858 DllPath
:=ExpandConstant('{app}\bin;{sys}');
860 // Load the list
of images from a
text file.
861 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
862 if LoadStringsFromFile(FileName
,ImageNames
) then begin
863 Count
:=GetArrayLength(ImageNames
)-1;
864 for i
:=0 to Count
do begin
865 FileName
:=AppDir
+'\'+ImageNames[i];
866 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
867 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
872 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
879 // Load the built-ins from a text file.
880 FileName:=AppDir+'\
{#APP_BUILTINS}';
881 if LoadStringsFromFile(FileName,BuiltIns) then begin
882 Count:=GetArrayLength(BuiltIns)-1;
884 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
885 for i:=0 to Count do begin
886 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
887 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
888 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
892 // Create built
-ins
as aliases
for git
.exe
.
893 for i
:=0 to Count
do begin
894 FileName
:=AppDir
+'\'+BuiltIns[i];
896 // Delete any existing built-in.
897 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
898 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
903 // This will throw an exception on pre-Win2k systems.
904 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
907 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
910 if not LinkCreated then begin
911 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
912 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
913 // This is not a critical error, Git could basically be used without the
914 // aliases for built-ins, so we continue.
919 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
920 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
922 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
923 FileName:=AppDir+'\bin
\'+FindRec
.name
;
924 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
925 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
928 until not FindNext(FindRec
);
932 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
933 MsgBox(Msg
,mbError
,MB_OK
);
935 // This
is not a critical error
, Git could basically be used without the
936 // aliases
for built
-ins
, so we continue
.
943 if RdbCRLF
[GC_LFOnly
].checked
then begin
944 Cmd
:='core.autocrlf input';
945 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
946 Cmd
:='core.autocrlf true';
948 Cmd
:='core.autocrlf false';
950 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
951 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
952 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
953 MsgBox(Msg
,mbError
,MB_OK
);
955 // This
is not a critical error
, the user can probably fix it manually
,
960 Modify the environment
962 This must happen no later than ssPostInstall to make
963 "ChangesEnvironment=yes" not happend before the change!
966 FileName
:=AppDir
+'\setup.ini';
968 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
969 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
970 if (GetArrayLength(EnvSSH
)=1) and
971 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
972 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
973 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
974 MsgBox(Msg
,mbError
,MB_OK
);
976 // This
is not a critical error
, the user can probably fix it manually
,
981 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
982 if (GetArrayLength(EnvSSH
)=1) and
983 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
984 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
985 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
986 MsgBox(Msg
,mbError
,MB_OK
);
988 // This
is not a critical error
, the user can probably fix it manually
,
993 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
994 SetArrayLength(EnvSSH
,1);
995 EnvSSH
[0]:=EdtPlink
.Text;
997 // Set GIT_SSH
as specified by the user
.
998 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
999 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
1000 MsgBox(Msg
,mbError
,MB_OK
);
1002 // This
is not a critical error
, the user can probably fix it manually
,
1006 // Mark that we have changed GIT_SSH by writing its value
to a
file.
1007 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
1008 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1009 MsgBox(Msg
,mbError
,MB_OK
);
1011 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1015 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
1016 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
1017 MsgBox(Msg
,mbError
,MB_OK
);
1019 // This
is not a critical error
, the user can probably fix it manually
,
1023 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1024 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1025 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1026 MsgBox(Msg
,mbError
,MB_OK
);
1028 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1033 // Get the current user
's directories in PATH.
1034 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1036 // First, remove the installation directory from PATH in any case.
1037 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1038 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1043 // Delete HOME if a previous installation modified it.
1044 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1045 if (GetArrayLength(EnvHome)=1) and
1046 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1047 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1048 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1049 MsgBox(Msg,mbError,MB_OK);
1051 // This is not a critical error, the user can probably fix it manually,
1056 // Modify the PATH variable as requested by the user.
1057 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1058 i:=GetArrayLength(EnvPath);
1059 SetArrayLength(EnvPath,i+1);
1061 // List \cmd before \bin so \cmd has higher priority and programs in
1062 // there will be called in favor of those in \bin.
1063 EnvPath[i]:=AppDir+'\cmd
';
1065 if RdbPath[GP_CmdTools].Checked then begin
1066 SetArrayLength(EnvPath,i+2);
1067 EnvPath[i+1]:=AppDir+'\bin
';
1069 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1070 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1071 i:=GetArrayLength(EnvHome);
1072 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1073 SetArrayLength(EnvHome,1);
1074 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1075 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1076 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1077 MsgBox(Msg,mbError,MB_OK);
1079 // This is not a critical error, the user can probably fix it manually,
1083 // Mark that we have changed HOME.
1084 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1085 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1086 MsgBox(Msg,mbError,MB_OK);
1088 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1095 // Set the current user's PATH directories
.
1096 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1097 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1098 MsgBox(Msg
,mbError
,MB_OK
);
1100 // This
is not a critical error
, the user can probably fix it manually
,
1105 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1108 GetWindowsVersionEx(Version
);
1109 if Version
.Major
<6 then begin
1110 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1111 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1113 Cmd
:=AppDir
+'\bin\sh.exe';
1114 TempName
:='--login -i';
1116 FileName
:=AppDir
+'\etc\git.ico';
1118 if IsComponentSelected('icons\quicklaunch') then begin
1120 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1124 , '%HOMEDRIVE%%HOMEPATH%'
1130 if IsComponentSelected('icons\desktop') then begin
1132 GetShellFolder('desktop')+'\Git Bash.lnk'
1136 , '%HOMEDRIVE%%HOMEPATH%'
1143 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1144 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1145 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1147 AppDir
+'\Git Bash.lnk'
1158 Create the Windows Explorer integrations
1161 if IsAdminLoggedOn
then begin
1162 RootKey
:=HKEY_LOCAL_MACHINE
;
1164 RootKey
:=HKEY_CURRENT_USER
;
1167 if IsComponentSelected('ext\reg\shellhere') then begin
1168 Msg
:='Git Ba&sh Here';
1169 Cmd
:='"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"';
1170 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','',Msg
)) or
1171 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Cmd
)) or
1172 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1173 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell','',Msg
)) or
1174 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_shell\command','',Cmd
)) then begin
1175 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1176 MsgBox(Msg
,mbError
,MB_OK
);
1178 // This
is not a critical error
, the user can probably fix it manually
,
1183 if IsComponentSelected('ext\reg\guihere') then begin
1184 Msg
:='Git &GUI Here';
1185 Cmd
:='"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"';
1186 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','',Msg
)) or
1187 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Cmd
)) or
1188 (StringChangeEx(Cmd
,'%1','%v',false)<>1) or
1189 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui','',Msg
)) or
1190 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\Background\shell\git_gui\command','',Cmd
)) then begin
1191 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1192 MsgBox(Msg
,mbError
,MB_OK
);
1194 // This
is not a critical error
, the user can probably fix it manually
,
1199 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1200 if IsComponentSelected('ext\cheetah') then begin
1201 DeleteContextMenuEntries
;
1203 if isWin64
then begin
1204 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1206 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1208 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1209 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1214 Restart any processes that were shut down via the Restart Manager
1217 if SessionHandle
>0 then try
1218 RmRestart(SessionHandle
,0,0);
1219 RmEndSession(SessionHandle
);
1221 Log('Line {#__LINE__}: RmRestart not supported.');
1225 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1229 // Git Path options
.
1231 if RdbPath
[GP_BashOnly
].Checked
then begin
1233 end else if RdbPath
[GP_Cmd
].Checked
then begin
1235 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1238 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1242 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1244 end else if RdbSSH
[GS_Plink
].Checked
then begin
1246 SetPreviousData(PreviousDataKey
,'Plink Path',EdtPlink
.Text);
1248 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1250 // Line ending conversion options
.
1252 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1254 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1256 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1257 Data
:='CRLFCommitAsIs';
1259 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1266 function InitializeUninstall
:Boolean;
1270 ExitButton
,RefreshButton
:TButton
;
1274 Form
:=CreateCustomForm
;
1276 Form
.Caption
:='Git Uninstall: Removing in-use files';
1277 Form
.ClientWidth
:=ScaleX(500);
1278 Form
.ClientHeight
:=ScaleY(256);
1281 Info
:=TLabel
.Create(Form
);
1287 Caption
:='The following applications use files that need to be removed, please close them.';
1290 ContinueButton
:=TButton
.Create(Form
);
1291 with ContinueButton
do begin
1293 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1294 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1297 Caption
:='Continue';
1301 ExitButton
:=TButton
.Create(Form
);
1302 with ExitButton
do begin
1304 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1305 Top
:=ContinueButton
.Top
;
1309 ModalResult
:=mrCancel
;
1313 RefreshButton
:=TButton
.Create(Form
);
1314 with RefreshButton
do begin
1317 Top
:=ExitButton
.Top
;
1321 OnClick
:=@RefreshProcessList
;
1324 ProcessesListBox
:=TListBox
.Create(Form
);
1325 with ProcessesListBox
do begin
1328 Top
:=Info
.Top
+Info
.Height
+11;
1329 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1330 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1333 Form
.ActiveControl
:=ContinueButton
;
1335 RefreshProcessList(NIL);
1336 if GetArrayLength(Processes
)>0 then begin
1337 // Now that these dialogs are going
to be shown
, we should probably
1338 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1339 // unfortunately that
is not possible
with Inno Setup currently
.
1340 Result
:=(Form
.ShowModal()=mrOk
);
1342 // Note
: The number
of processes might have changed during a refresh
.
1343 if Result
and (GetArrayLength(Processes
)>0) then begin
1345 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1346 'Are you sure you want to continue anyway?',
1359 // Even though the name
of this
function suggests otherwise most
of the
1360 // code below
is only executed right before the actual uninstallation
.
1361 // This happens because
of the
if-guard right
in the beginning
of this
1363 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1365 AppDir
,FileName
,Msg
:String;
1366 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1369 if CurUninstallStep
<>usUninstall
then begin
1373 // Reset the console
font (the FontType
is reset
in the Registry section
).
1374 if IsComponentInstalled('consolefont') then begin
1375 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1376 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1377 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1378 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1383 Modify the environment
1385 This must happen no later than usUninstall to make
1386 "ChangesEnvironment=yes" not happend before the change!
1389 AppDir
:=ExpandConstant('{app}');
1390 FileName
:=AppDir
+'\setup.ini';
1392 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1393 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1394 if (GetArrayLength(EnvSSH)=1) and
1395 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1396 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1397 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1398 MsgBox(Msg,mbError,MB_OK);
1400 // This is not a critical error, the user can probably fix it manually,
1405 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1406 if (GetArrayLength(EnvSSH)=1) and
1407 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1408 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1409 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1410 MsgBox(Msg,mbError,MB_OK);
1412 // This is not a critical error, the user can probably fix it manually,
1417 // Get the current user's directories
in PATH
.
1418 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1420 // Remove the installation directory from PATH
in any
case, even
if it
1421 // was
not added by the installer
.
1422 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1423 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1428 // Reset the current user
's directories in PATH.
1429 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1430 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1431 MsgBox(Msg,mbError,MB_OK);
1433 // This is not a critical error, the user can probably fix it manually,
1437 // Reset the current user's HOME
if we modified it
.
1438 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1439 if (GetArrayLength(EnvHome
)=1) and
1440 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1441 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1442 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1443 MsgBox(Msg
,mbError
,MB_OK
);
1445 // This
is not a critical error
, the user can probably fix it manually
,
1450 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1451 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1452 MsgBox(Msg
,mbError
,MB_OK
);
1454 // This
is not a critical error
, the user can probably fix it manually
,
1459 Delete the Windows Explorer integrations
1462 DeleteContextMenuEntries
;
1464 if isWin64
then begin
1465 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1467 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1469 if FileExists(FileName
) then begin
1470 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1471 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1472 MsgBox(Msg
,mbError
,MB_OK
);
1476 if not DeleteFile(FileName
) then begin
1477 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1478 MsgBox(Msg
,mbError
,MB_OK
);