1 ; Uncomment the line below to be able to compile the script from within the IDE.
2 ;#define COMPILE_FROM_IDE
5 #ifdef COMPILE_FROM_IDE
6 #define APP_VERSION
'Snapshot'
8 #define APP_VERSION
'%APPVERSION%'
10 #define APP_URL
'http://msysgit.googlecode.com/'
11 #define APP_BUILTINS
'etc\fileList-builtins.txt'
12 #define APP_BINDIMAGE
'etc\fileList-bindimage.txt'
14 #define COMP_CONSOLE_FONT
'Use a TrueType font in all console windows (not only for Git Bash)'
16 #define DROP_HANDLER_GUID
'{{86C86720-42A0-1069-A2E8-08002B30309D}}'
20 Compression
=lzma2
/ultra
21 LZMAUseSeparateProcess
=yes
22 OutputBaseFilename
={#APP_NAME+'-'+APP_VERSION}
23 OutputDir
={#GetEnv('USERPROFILE')}
25 #ifdef COMPILE_FROM_IDE
26 SourceDir
={#GetEnv('TEMP')}\WinGit
32 AppPublisher
=The Git Development Community
33 AppPublisherURL
={#APP_URL}
34 AppVersion
={#APP_VERSION}
35 ChangesEnvironment
=yes
36 DefaultDirName
={pf}\
{#APP_NAME}
38 DefaultGroupName
={#APP_NAME}
39 DisableProgramGroupPage
=auto
41 InfoBeforeFile
=gpl
-2.0.rtf
42 PrivilegesRequired
=none
43 UninstallDisplayIcon
={app}\etc\git
.ico
44 #ifndef COMPILE_FROM_IDE
45 #
if Pos('-',APP_VERSION
)>0
46 VersionInfoVersion
={#Copy(APP_VERSION,1,Pos('-',APP_VERSION)-1)}
48 VersionInfoVersion
={#APP_VERSION}
53 SetupIconFile
=etc\git
.ico
54 WizardImageBackColor
=clWhite
56 WizardImageFile
=git
.bmp
57 WizardSmallImageFile
=gitsmall
.bmp
60 ; Define a dummy type to avoid getting the default ones.
61 Name
: custom
; Description
: Custom installation
; Flags
: iscustom
64 Name
: icons
; Description
: Additional icons
; Types
: custom
65 Name
: icons\quicklaunch
; Description
: In the Quick Launch
; Types
: custom
66 Name
: icons\desktop
; Description
: On the Desktop
; Types
: custom
67 Name
: ext
; Description
: Windows Explorer integration
; Types
: custom
68 Name
: ext
\reg
; Description
: Simple context
menu (Registry based
); Flags
: exclusive; Types
: custom
69 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: custom
70 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: custom
71 Name
: ext\cheetah
; Description
: Advanced context
menu (git
-cheetah plugin
); Flags
: exclusive; Types
: custom
72 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: custom
73 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: custom
74 Name
: consolefont
; Description
: {#COMP_CONSOLE_FONT}; Types
: custom
77 ; Install files that might be in use during setup under a different name.
78 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
79 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
; AfterInstall
: DeleteFromVirtualStore
81 Source
: *; DestDir
: {app}; Excludes
: \
*.bmp
, gpl
-2.0.rtf
, \
*.iss
, \tmp
.*, \bin\
*install
*, \git
-cheetah\git_shell_ext
.dll
, \git
-cheetah\git_shell_ext64
.dll
; Flags
: recursesubdirs replacesameversion sortfilesbyextension; AfterInstall
: DeleteFromVirtualStore
82 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion; AfterInstall
: DeleteFromVirtualStore
85 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
86 Name
: {group}\Git Bash
; Filename
: {syswow64}\cmd
.exe
; Parameters
: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; OnlyBelowVersion
: 6.0
87 Name
: {group}\Git Bash
; Filename
: {app}\bin\sh
.exe
; Parameters
: "--login -i"; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
; MinVersion
: 6.0
90 BeveledLabel
={#APP_URL}
91 SetupAppTitle
={#APP_NAME} Setup
92 SetupWindowTitle
={#APP_NAME} Setup
95 ; There is no "Console" key in HKLM.
96 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
97 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
98 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
99 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
101 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
102 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
103 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
104 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
106 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
107 ; is a member of the local Administrators group or not (see the "Check" argument).
109 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
110 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
111 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
112 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
113 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
114 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
115 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
117 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
118 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
119 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
120 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
121 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
122 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
124 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
125 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
126 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
127 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
128 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
129 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
131 ; Associate .sh extension with sh.exe so those files are double-clickable,
132 ; startable from cmd.exe, and when files are dropped on them they are passed
133 ; as arguments to the script.
135 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
136 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
137 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
138 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: "{syswow64}\cmd.exe /C """"{app}\bin\sh.exe"" ""--login"" ""%1"" %*"""; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
139 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
140 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
142 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
143 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
144 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
145 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
146 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\DefaultIcon
; ValueType
: string; ValueData
: "%SystemRoot%\System32\shell32.dll,-153"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
147 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
150 ; Delete the built-ins.
151 Type: files; Name
: {app}\bin\git
-*.exe
152 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
153 Type: files; Name
: {app}\libexec\git
-core\git
.exe
155 ; Delete any (temporary) git-cheetah files.
156 Type: files; Name
: {app}\git
-cheetah\
*.*
158 ; Delete any manually created shortcuts.
159 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
160 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
161 Type: files; Name
: {app}\Git Bash
.lnk
163 ; Delete a home directory inside the msysGit directory.
164 Type: dirifempty; Name
: {app}\home\
{username}
165 Type: dirifempty; Name
: {app}\home
168 #include
"helpers.inc.iss"
169 #include
"environment.inc.iss"
170 #include
"putty.inc.iss"
171 #include
"modules.inc.iss"
173 procedure DeleteFromVirtualStore
;
175 VirtualStore
,FileName
:String;
178 VirtualStore
:=AddBackslash(ExpandConstant('{localappdata}'))+'VirtualStore';
179 FileName
:=ExpandConstant(CurrentFileName
);
180 DriveChars
:=Length(ExtractFileDrive(FileName
));
181 if DriveChars
>0 then begin
182 Delete(FileName
,1,DriveChars
);
183 FileName
:=VirtualStore
+FileName
;
184 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
185 Log('Line {#__LINE__}: Unable delete "'+FileName
+'".');
186 // This
is not a critical error
, the user can probably fix it manually
,
192 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
194 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
196 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
199 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
200 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
212 // Git line ending conversion options
.
215 GC_CRLFCommitAsIs
= 3;
217 // BindImageEx API constants
.
218 BIND_NO_BOUND_IMPORTS
= $00000001;
219 BIND_NO_UPDATE
= $00000002;
220 BIND_ALL_IMAGES
= $00000004;
221 BIND_CACHE_IMPORT_DLLS
= $00000008;
224 // Wizard page
and variables
for the Path options
.
225 PathPage
:TWizardPage
;
226 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
228 // Wizard page
and variables
for the SSH options
.
229 PuTTYPage
:TWizardPage
;
230 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
233 // Wizard page
and variables
for the line ending conversion options
.
234 CRLFPage
:TWizardPage
;
235 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
237 // Wizard page
and variables
for the processes page
.
239 Processes
:ProcessList
;
240 ProcessesPage
:TWizardPage
;
241 ProcessesListBox
:TListBox
;
242 ProcessesRefresh
,ContinueButton
:TButton
;
244 procedure BrowseForPuTTYFolder(Sender
:TObject
);
248 Path
:=ExtractFilePath(EdtPlink
.Text);
249 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
250 if FileExists(Path
+'\TortoisePlink.exe') then begin
251 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
252 RdbSSH
[GS_Plink
].Checked
:=True;
253 end else if FileExists(Path
+'\plink.exe') then begin
254 EdtPlink
.Text:=Path
+'\plink.exe';
255 RdbSSH
[GS_Plink
].Checked
:=True;
257 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
261 procedure DeleteContextMenuEntries
;
263 AppDir
,Command
,Msg
:String;
266 AppDir
:=ExpandConstant('{app}');
268 if IsAdminLoggedOn
then begin
269 RootKey
:=HKEY_LOCAL_MACHINE
;
271 RootKey
:=HKEY_CURRENT_USER
;
275 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command
);
276 if Pos(AppDir
,Command
)>0 then begin
277 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
278 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash Here" shell extension.';
279 MsgBox(Msg
,mbError
,MB_OK
);
281 // This
is not a critical error
, the user can probably fix it manually
,
287 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command
);
288 if Pos(AppDir
,Command
)>0 then begin
289 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
290 Msg
:='Line {#__LINE__}: Unable to remove "Git GUI Here" shell extension.';
291 MsgBox(Msg
,mbError
,MB_OK
);
293 // This
is not a critical error
, the user can probably fix it manually
,
299 procedure RefreshProcessList(Sender
:TObject
);
301 Version
:TWindowsVersion
;
302 Modules
:TArrayOfString
;
303 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
306 ManualClosingRequired
:Boolean;
308 GetWindowsVersionEx(Version
);
310 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
311 if Version
.Major
>=6 then begin
312 SetArrayLength(Modules
,5);
313 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
314 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
315 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
316 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
317 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
318 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
320 SetArrayLength(Modules
,3);
321 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
322 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
323 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
324 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
326 SetArrayLength(Modules
,2);
327 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
328 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
329 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
331 // Misuse the
"Restartable" flag
to indicate which processes are required
332 // to be closed before setup can continue
, and which just should be closed
333 // in order
to make changes take effect immediately
.
334 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
335 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
336 Processes
[i
]:=ProcsCloseRequired
[i
];
337 Processes
[i
].Restartable
:=False;
339 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
340 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
341 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
345 ManualClosingRequired
:=False;
347 ProcessesListBox
.Items
.Clear
;
348 if (Sender
=NIL) or (SessionHandle
>0) then begin
349 for i
:=0 to GetArrayLength(Processes
)-1 do begin
350 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
351 if Processes
[i
].Restartable
then begin
352 Caption
:=Caption
+', closing is optional';
354 Caption
:=Caption
+', closing is required';
355 ManualClosingRequired
:=True;
357 Caption
:=Caption
+')';
358 ProcessesListBox
.Items
.Append(Caption
);
362 if ContinueButton
<>NIL then begin
363 ContinueButton
.Enabled
:=not ManualClosingRequired
;
371 procedure InitializeWizard
;
374 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
375 LblOpenSSH
,LblPlink
:TLabel
;
376 PuTTYSessions
:TArrayOfString
;
377 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
382 PrevPageID
:=wpSelectProgramGroup
;
385 * Create a custom page for modifying the environment.
388 PathPage
:=CreateCustomPage(
390 'Adjusting your PATH environment',
391 'How would you like to use Git from the command line?'
393 PrevPageID
:=PathPage
.ID
;
396 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
397 with RdbPath
[GP_BashOnly
] do begin
398 Parent
:=PathPage
.Surface
;
399 Caption
:='Use Git Bash only';
404 Font
.Style
:=[fsBold
];
408 LblGitBash
:=TLabel
.Create(PathPage
);
409 with LblGitBash
do begin
410 Parent
:=PathPage
.Surface
;
412 'This is the most conservative choice if you are concerned about the stability' + #
13 +
413 'of your system. Your PATH will not be modified.';
421 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
422 with RdbPath
[GP_Cmd
] do begin
423 Parent
:=PathPage
.Surface
;
424 Caption
:='Run Git from the Windows Command Prompt';
429 Font
.Style
:=[fsBold
];
432 LblGitCmd
:=TLabel
.Create(PathPage
);
433 with LblGitCmd
do begin
434 Parent
:=PathPage
.Surface
;
436 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
437 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
438 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
446 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
447 with RdbPath
[GP_CmdTools
] do begin
448 Parent
:=PathPage
.Surface
;
449 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
454 Font
.Style
:=[fsBold
];
457 LblGitCmdTools
:=TLabel
.Create(PathPage
);
458 with LblGitCmdTools
do begin
459 Parent
:=PathPage
.Surface
;
460 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
466 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
467 with LblGitCmdToolsWarn
do begin
468 Parent
:=PathPage
.Surface
;
470 'Warning: This will override Windows tools like find.exe and' + #
13 +
471 'sort.exe. Select this option only if you understand the implications.';
477 Font
.Style
:=[fsBold
];
480 // Restore the setting chosen during a previous install
.
481 Data
:=GetPreviousData('Path Option','BashOnly');
482 if Data
='BashOnly' then begin
483 RdbPath
[GP_BashOnly
].Checked
:=True;
484 end else if Data
='Cmd' then begin
485 RdbPath
[GP_Cmd
].Checked
:=True;
486 end else if Data
='CmdTools' then begin
487 RdbPath
[GP_CmdTools
].Checked
:=True;
491 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
492 * if at least one PuTTY session is found in the Registry.
495 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
496 PuTTYPage
:=CreateCustomPage(
498 'Choosing the SSH executable',
499 'Which Secure Shell client program would you like Git to use?'
501 PrevPageID
:=PuTTYPage
.ID
;
504 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
505 with RdbSSH
[GS_OpenSSH
] do begin
506 Parent
:=PuTTYPage
.Surface
;
507 Caption
:='Use OpenSSH';
512 Font
.Style
:=[fsBold
];
516 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
517 with LblOpenSSH
do begin
518 Parent
:=PuTTYPage
.Surface
;
520 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
521 'environment variables will not be modified.';
529 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
530 with RdbSSH
[GS_Plink
] do begin
531 Parent
:=PuTTYPage
.Surface
;
532 Caption
:='Use (Tortoise)Plink';
537 Font
.Style
:=[fsBold
];
540 LblPlink
:=TLabel
.Create(PuTTYPage
);
541 with LblPlink
do begin
542 Parent
:=PuTTYPage
.Surface
;
544 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
545 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
546 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
547 'variables will be adjusted to point to the following executable:';
553 EdtPlink
:=TEdit
.Create(PuTTYPage
);
554 with EdtPlink
do begin
555 Parent
:=PuTTYPage
.Surface
;
556 Text:=GetPuTTYLocation
;
557 if not FileExists(Text) then begin
565 BtnPlink
:=TButton
.Create(PuTTYPage
);
566 with BtnPlink
do begin
567 Parent
:=PuTTYPage
.Surface
;
569 OnClick
:=@BrowseForPuTTYFolder
;
576 // Restore the setting chosen during a previous install
.
577 Data
:=GetPreviousData('SSH Option','OpenSSH');
578 if Data
='OpenSSH' then begin
579 RdbSSH
[GS_OpenSSH
].Checked
:=True;
580 end else if Data
='Plink' then begin
581 RdbSSH
[GS_Plink
].Checked
:=True;
588 * Create a custom page for the core.autocrlf setting.
591 CRLFPage
:=CreateCustomPage(
593 'Configuring the line ending conversions',
594 'How should Git treat line endings in text files?'
596 PrevPageID
:=CRLFPage
.ID
;
599 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
600 with RdbCRLF
[GC_CRLFAlways
] do begin
601 Parent
:=CRLFPage
.Surface
;
602 Caption
:='Checkout Windows-style, commit Unix-style line endings';
607 Font
.Style
:=[fsBold
];
611 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
612 with LblCRLFAlways
do begin
613 Parent
:=CRLFPage
.Surface
;
615 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
616 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
617 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
625 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
626 with RdbCRLF
[GC_LFOnly
] do begin
627 Parent
:=CRLFPage
.Surface
;
628 Caption
:='Checkout as-is, commit Unix-style line endings';
633 Font
.Style
:=[fsBold
];
637 LblLFOnly
:=TLabel
.Create(CRLFPage
);
638 with LblLFOnly
do begin
639 Parent
:=CRLFPage
.Surface
;
641 'Git will not perform any conversion when checking out text files. When' + #
13 +
642 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
643 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
651 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
652 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
653 Parent
:=CRLFPage
.Surface
;
654 Caption
:='Checkout as-is, commit as-is';
659 Font
.Style
:=[fsBold
];
663 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
664 with LblCRLFCommitAsIs
do begin
665 Parent
:=CRLFPage
.Surface
;
667 'Git will not perform any conversions when checking out or committing' + #
13 +
668 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
669 'projects ("core.autocrlf" is set to "false").';
676 // Restore the setting chosen during a previous install
.
677 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
678 if Data
='LFOnly' then begin
679 RdbCRLF
[GC_LFOnly
].Checked
:=True;
680 end else if Data
='CRLFAlways' then begin
681 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
682 end else if Data
='CRLFCommitAsIs' then begin
683 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
687 * Create a custom page for finding the processes that lock a module.
690 ProcessesPage
:=CreateCustomPage(
692 'Replacing in-use files',
693 'The following applications use files that need to be replaced, please close them.'
696 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
697 with ProcessesListBox
do begin
698 Parent
:=ProcessesPage
.Surface
;
699 Width
:=ProcessesPage
.SurfaceWidth
;
700 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
703 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
704 with ProcessesRefresh
do begin
706 Width
:=WizardForm
.CancelButton
.Width
;
707 Height
:=WizardForm
.CancelButton
.Height
;
708 Top
:=WizardForm
.CancelButton
.Top
;
709 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
711 OnClick
:=@RefreshProcessList
;
714 // This button
is only used by the uninstaller
.
717 // Initially hide the Refresh button
, show it when the process page becomes current
.
718 ProcessesRefresh
.Hide
;
721 function ShouldSkipPage(PageID
:Integer):Boolean;
723 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
724 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
725 RefreshProcessList(NIL);
726 Result
:=(GetArrayLength(Processes
)=0);
732 procedure CurPageChanged(CurPageID
:Integer);
736 if CurPageID
=wpSelectDir
then begin
737 if not IsDirWritable(WizardDirValue
) then begin
738 // If the default directory
is not writable
, choose another default that most likely
is.
739 // This will be checked later again when the user clicks
"Next".
740 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
744 // Uncheck the console font option by default
.
745 if CurPageID
=wpSelectComponents
then begin
746 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
747 if WizardForm
.ComponentsList
.ItemCaption
[i
]='{#COMP_CONSOLE_FONT}' then begin
748 WizardForm
.ComponentsList
.Checked
[i
]:=False;
754 // Show the
"Refresh" button only on the processes page
.
755 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
756 ProcessesRefresh
.Show
;
758 ProcessesRefresh
.Hide
;
762 function NextButtonClick(CurPageID
:Integer):Boolean;
765 Version
:TWindowsVersion
;
769 if CurPageID
=wpSelectDir
then begin
770 if not IsDirWritable(WizardDirValue
) then begin
772 'The specified installation directory does not seem to be writable. ' +
773 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
782 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
783 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
784 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
785 if not Result
then begin
786 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
788 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
789 // It would have been nicer
to just disable the
"Next" button
, but the
790 // WizardForm
exports the button just
read-only
.
791 for i
:=0 to GetArrayLength(Processes
)-1 do begin
792 if not Processes
[i
].Restartable
then begin
793 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
799 Result
:=(GetArrayLength(Processes
)=0);
801 if not Result
then begin
802 GetWindowsVersionEx(Version
);
803 if Version
.Major
>=6 then begin
805 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
806 'Are you sure you want to continue?',
812 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
813 'Are you sure you want to continue anyway?',
822 procedure CurStepChanged(CurStep
:TSetupStep
);
824 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
825 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
831 if CurStep
=ssInstall
then begin
832 // Shutdown locking processes just before the actual installation starts
.
833 if SessionHandle
>0 then try
834 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
836 Log('Line {#__LINE__}: RmShutdown not supported.');
842 // Make sure the code below
is only executed just after the actual installation finishes
.
843 if CurStep
<>ssPostInstall
then begin
847 AppDir
:=ExpandConstant('{app}');
850 Bind the imported function addresses
854 DllPath
:=ExpandConstant('{app}\bin;{sys}');
856 // Load the list
of images from a
text file.
857 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
858 if LoadStringsFromFile(FileName
,ImageNames
) then begin
859 Count
:=GetArrayLength(ImageNames
)-1;
860 for i
:=0 to Count
do begin
861 FileName
:=AppDir
+'\'+ImageNames[i];
862 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
863 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
868 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
875 // Load the built-ins from a text file.
876 FileName:=AppDir+'\
{#APP_BUILTINS}';
877 if LoadStringsFromFile(FileName,BuiltIns) then begin
878 Count:=GetArrayLength(BuiltIns)-1;
880 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
881 for i:=0 to Count do begin
882 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
883 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
884 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
888 // Create built
-ins
as aliases
for git
.exe
.
889 for i
:=0 to Count
do begin
890 FileName
:=AppDir
+'\'+BuiltIns[i];
892 // Delete any existing built-in.
893 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
894 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
899 // This will throw an exception on pre-Win2k systems.
900 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
903 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
906 if not LinkCreated then begin
907 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
908 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
909 // This is not a critical error, Git could basically be used without the
910 // aliases for built-ins, so we continue.
915 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
916 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
918 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
919 FileName:=AppDir+'\bin
\'+FindRec
.name
;
920 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
921 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
924 until not FindNext(FindRec
);
928 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
929 MsgBox(Msg
,mbError
,MB_OK
);
931 // This
is not a critical error
, Git could basically be used without the
932 // aliases
for built
-ins
, so we continue
.
939 if RdbCRLF
[GC_LFOnly
].checked
then begin
940 Cmd
:='core.autocrlf input';
941 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
942 Cmd
:='core.autocrlf true';
944 Cmd
:='core.autocrlf false';
946 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
947 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
948 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
949 MsgBox(Msg
,mbError
,MB_OK
);
951 // This
is not a critical error
, the user can probably fix it manually
,
956 Modify the environment
958 This must happen no later than ssPostInstall to make
959 "ChangesEnvironment=yes" not happend before the change!
962 FileName
:=AppDir
+'\setup.ini';
964 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
965 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
966 if (GetArrayLength(EnvSSH
)=1) and
967 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
968 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
969 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
970 MsgBox(Msg
,mbError
,MB_OK
);
972 // This
is not a critical error
, the user can probably fix it manually
,
977 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
978 if (GetArrayLength(EnvSSH
)=1) and
979 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
980 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
981 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
982 MsgBox(Msg
,mbError
,MB_OK
);
984 // This
is not a critical error
, the user can probably fix it manually
,
989 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
990 SetArrayLength(EnvSSH
,1);
991 EnvSSH
[0]:=EdtPlink
.Text;
993 // Set GIT_SSH
as specified by the user
.
994 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
995 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
996 MsgBox(Msg
,mbError
,MB_OK
);
998 // This
is not a critical error
, the user can probably fix it manually
,
1002 // Mark that we have changed GIT_SSH by writing its value
to a
file.
1003 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
1004 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1005 MsgBox(Msg
,mbError
,MB_OK
);
1007 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1011 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
1012 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
1013 MsgBox(Msg
,mbError
,MB_OK
);
1015 // This
is not a critical error
, the user can probably fix it manually
,
1019 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1020 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1021 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1022 MsgBox(Msg
,mbError
,MB_OK
);
1024 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1029 // Get the current user
's directories in PATH.
1030 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1032 // First, remove the installation directory from PATH in any case.
1033 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1034 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1039 // Delete HOME if a previous installation modified it.
1040 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1041 if (GetArrayLength(EnvHome)=1) and
1042 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1043 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1044 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1045 MsgBox(Msg,mbError,MB_OK);
1047 // This is not a critical error, the user can probably fix it manually,
1052 // Modify the PATH variable as requested by the user.
1053 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1054 i:=GetArrayLength(EnvPath);
1055 SetArrayLength(EnvPath,i+1);
1057 // List \cmd before \bin so \cmd has higher priority and programs in
1058 // there will be called in favor of those in \bin.
1059 EnvPath[i]:=AppDir+'\cmd
';
1061 if RdbPath[GP_CmdTools].Checked then begin
1062 SetArrayLength(EnvPath,i+2);
1063 EnvPath[i+1]:=AppDir+'\bin
';
1065 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1066 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1067 i:=GetArrayLength(EnvHome);
1068 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1069 SetArrayLength(EnvHome,1);
1070 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1071 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1072 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1073 MsgBox(Msg,mbError,MB_OK);
1075 // This is not a critical error, the user can probably fix it manually,
1079 // Mark that we have changed HOME.
1080 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1081 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1082 MsgBox(Msg,mbError,MB_OK);
1084 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1091 // Set the current user's PATH directories
.
1092 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1093 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1094 MsgBox(Msg
,mbError
,MB_OK
);
1096 // This
is not a critical error
, the user can probably fix it manually
,
1101 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1104 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1105 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1106 FileName
:=AppDir
+'\etc\git.ico';
1108 if IsComponentSelected('icons\quicklaunch') then begin
1110 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1114 , '%HOMEDRIVE%%HOMEPATH%'
1120 if IsComponentSelected('icons\desktop') then begin
1122 GetShellFolder('desktop')+'\Git Bash.lnk'
1126 , '%HOMEDRIVE%%HOMEPATH%'
1133 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1134 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1135 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1137 AppDir
+'\Git Bash.lnk'
1148 Create the Windows Explorer integrations
1151 if IsAdminLoggedOn
then begin
1152 RootKey
:=HKEY_LOCAL_MACHINE
;
1154 RootKey
:=HKEY_CURRENT_USER
;
1157 if IsComponentSelected('ext\reg\shellhere') then begin
1158 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
1159 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','','"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"')) then begin
1160 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1161 MsgBox(Msg
,mbError
,MB_OK
);
1163 // This
is not a critical error
, the user can probably fix it manually
,
1168 if IsComponentSelected('ext\reg\guihere') then begin
1169 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
1170 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','','"'+AppDir
+'\bin\wish.exe" "'+AppDir
+'\libexec\git-core\git-gui" "--working-dir" "%1"')) then begin
1171 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1172 MsgBox(Msg
,mbError
,MB_OK
);
1174 // This
is not a critical error
, the user can probably fix it manually
,
1179 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1180 if IsComponentSelected('ext\cheetah') then begin
1181 DeleteContextMenuEntries
;
1183 if isWin64
then begin
1184 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1186 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1188 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1189 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1194 Restart any processes that were shut down via the Restart Manager
1197 if SessionHandle
>0 then try
1198 RmRestart(SessionHandle
,0,0);
1199 RmEndSession(SessionHandle
);
1201 Log('Line {#__LINE__}: RmRestart not supported.');
1205 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1209 // Git Path options
.
1211 if RdbPath
[GP_BashOnly
].Checked
then begin
1213 end else if RdbPath
[GP_Cmd
].Checked
then begin
1215 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1218 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1222 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1224 end else if RdbSSH
[GS_Plink
].Checked
then begin
1227 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1229 // Line ending conversion options
.
1231 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1233 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1235 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1236 Data
:='CRLFCommitAsIs';
1238 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1245 function InitializeUninstall
:Boolean;
1249 ExitButton
,RefreshButton
:TButton
;
1253 Form
:=CreateCustomForm
;
1255 Form
.Caption
:='Git Uninstall: Removing in-use files';
1256 Form
.ClientWidth
:=ScaleX(500);
1257 Form
.ClientHeight
:=ScaleY(256);
1260 Info
:=TLabel
.Create(Form
);
1266 Caption
:='The following applications use files that need to be removed, please close them.';
1269 ContinueButton
:=TButton
.Create(Form
);
1270 with ContinueButton
do begin
1272 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1273 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1276 Caption
:='Continue';
1280 ExitButton
:=TButton
.Create(Form
);
1281 with ExitButton
do begin
1283 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1284 Top
:=ContinueButton
.Top
;
1288 ModalResult
:=mrCancel
;
1292 RefreshButton
:=TButton
.Create(Form
);
1293 with RefreshButton
do begin
1296 Top
:=ExitButton
.Top
;
1300 OnClick
:=@RefreshProcessList
;
1303 ProcessesListBox
:=TListBox
.Create(Form
);
1304 with ProcessesListBox
do begin
1307 Top
:=Info
.Top
+Info
.Height
+11;
1308 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1309 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1312 Form
.ActiveControl
:=ContinueButton
;
1314 RefreshProcessList(NIL);
1315 if GetArrayLength(Processes
)>0 then begin
1316 // Now that these dialogs are going
to be shown
, we should probably
1317 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1318 // unfortunately that
is not possible
with Inno Setup currently
.
1319 Result
:=(Form
.ShowModal()=mrOk
);
1321 // Note
: The number
of processes might have changed during a refresh
.
1322 if Result
and (GetArrayLength(Processes
)>0) then begin
1324 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1325 'Are you sure you want to continue anyway?',
1338 // Even though the name
of this
function suggests otherwise most
of the
1339 // code below
is only executed right before the actual uninstallation
.
1340 // This happens because
of the
if-guard right
in the beginning
of this
1342 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1344 AppDir
,FileName
,Msg
:String;
1345 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1348 if CurUninstallStep
<>usUninstall
then begin
1352 // Reset the console
font (the FontType
is reset
in the Registry section
).
1353 if IsComponentInstalled('consolefont') then begin
1354 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1355 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1356 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1357 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1362 Modify the environment
1364 This must happen no later than usUninstall to make
1365 "ChangesEnvironment=yes" not happend before the change!
1368 AppDir
:=ExpandConstant('{app}');
1369 FileName
:=AppDir
+'\setup.ini';
1371 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1372 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1373 if (GetArrayLength(EnvSSH)=1) and
1374 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1375 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1376 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1377 MsgBox(Msg,mbError,MB_OK);
1379 // This is not a critical error, the user can probably fix it manually,
1384 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1385 if (GetArrayLength(EnvSSH)=1) and
1386 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1387 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1388 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1389 MsgBox(Msg,mbError,MB_OK);
1391 // This is not a critical error, the user can probably fix it manually,
1396 // Get the current user's directories
in PATH
.
1397 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1399 // Remove the installation directory from PATH
in any
case, even
if it
1400 // was
not added by the installer
.
1401 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1402 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1407 // Reset the current user
's directories in PATH.
1408 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1409 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1410 MsgBox(Msg,mbError,MB_OK);
1412 // This is not a critical error, the user can probably fix it manually,
1416 // Reset the current user's HOME
if we modified it
.
1417 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1418 if (GetArrayLength(EnvHome
)=1) and
1419 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1420 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1421 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1422 MsgBox(Msg
,mbError
,MB_OK
);
1424 // This
is not a critical error
, the user can probably fix it manually
,
1429 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1430 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1431 MsgBox(Msg
,mbError
,MB_OK
);
1433 // This
is not a critical error
, the user can probably fix it manually
,
1438 Delete the Windows Explorer integrations
1441 DeleteContextMenuEntries
;
1443 if isWin64
then begin
1444 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1446 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1448 if FileExists(FileName
) then begin
1449 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1450 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1451 MsgBox(Msg
,mbError
,MB_OK
);
1455 if not DeleteFile(FileName
) then begin
1456 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1457 MsgBox(Msg
,mbError
,MB_OK
);