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
79 Source
: git
-cheetah\git_shell_ext64
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext64
.dll
.new
; Flags
: replacesameversion; Components
: ext\cheetah
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
82 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion
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
89 BeveledLabel
={#APP_URL}
90 SetupAppTitle
={#APP_NAME} Setup
91 SetupWindowTitle
={#APP_NAME} Setup
94 ; There is no "Console" key in HKLM.
95 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
96 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
97 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
98 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
100 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
101 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
102 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
103 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
105 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
106 ; is a member of the local Administrators group or not (see the "Check" argument).
108 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
109 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
110 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
111 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
112 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
113 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
114 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
116 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
117 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
118 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
119 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
120 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
121 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
123 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
124 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
125 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
126 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
127 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
128 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
130 ; Associate .sh extension with sh.exe so those files are double-clickable,
131 ; startable from cmd.exe, and when files are dropped on them they are passed
132 ; as arguments to the script.
134 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
135 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
136 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
137 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
138 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\DefaultIcon
; ValueType
: string; ValueData
: "%SystemRoot%\System32\shell32.dll,-153"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
139 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\ShellEx\DropHandler
; ValueType
: string; ValueData
: {#DROP_HANDLER_GUID}; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
141 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
142 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
143 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
144 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: "{syswow64}\cmd.exe /C """"{app}\bin\sh.exe"" ""--login"" ""%1"" %*"""; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
145 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
146 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
149 ; Delete the built-ins.
150 Type: files; Name
: {app}\bin\git
-*.exe
151 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
152 Type: files; Name
: {app}\libexec\git
-core\git
.exe
154 ; Delete any (temporary) git-cheetah files.
155 Type: files; Name
: {app}\git
-cheetah\
*.*
157 ; Delete any manually created shortcuts.
158 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
159 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
160 Type: files; Name
: {app}\Git Bash
.lnk
162 ; Delete a home directory inside the msysGit directory.
163 Type: dirifempty; Name
: {app}\home\
{username}
164 Type: dirifempty; Name
: {app}\home
167 #include
"helpers.inc.iss"
168 #include
"environment.inc.iss"
169 #include
"putty.inc.iss"
170 #include
"modules.inc.iss"
172 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
174 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
176 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
179 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
180 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
192 // Git line ending conversion options
.
195 GC_CRLFCommitAsIs
= 3;
197 // BindImageEx API constants
.
198 BIND_NO_BOUND_IMPORTS
= $00000001;
199 BIND_NO_UPDATE
= $00000002;
200 BIND_ALL_IMAGES
= $00000004;
201 BIND_CACHE_IMPORT_DLLS
= $00000008;
204 // Wizard page
and variables
for the Path options
.
205 PathPage
:TWizardPage
;
206 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
208 // Wizard page
and variables
for the SSH options
.
209 PuTTYPage
:TWizardPage
;
210 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
213 // Wizard page
and variables
for the line ending conversion options
.
214 CRLFPage
:TWizardPage
;
215 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
217 // Wizard page
and variables
for the processes page
.
219 Processes
:ProcessList
;
220 ProcessesPage
:TWizardPage
;
221 ProcessesListBox
:TListBox
;
222 ProcessesRefresh
,ContinueButton
:TButton
;
224 procedure BrowseForPuTTYFolder(Sender
:TObject
);
228 Path
:=ExtractFilePath(EdtPlink
.Text);
229 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
230 if FileExists(Path
+'\TortoisePlink.exe') then begin
231 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
232 RdbSSH
[GS_Plink
].Checked
:=True;
233 end else if FileExists(Path
+'\plink.exe') then begin
234 EdtPlink
.Text:=Path
+'\plink.exe';
235 RdbSSH
[GS_Plink
].Checked
:=True;
237 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
241 procedure DeleteContextMenuEntries
;
243 AppDir
,Command
,Msg
:String;
246 AppDir
:=ExpandConstant('{app}');
248 if IsAdminLoggedOn
then begin
249 RootKey
:=HKEY_LOCAL_MACHINE
;
251 RootKey
:=HKEY_CURRENT_USER
;
255 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command
);
256 if Pos(AppDir
,Command
)>0 then begin
257 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
258 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash Here" shell extension.';
259 MsgBox(Msg
,mbError
,MB_OK
);
261 // This
is not a critical error
, the user can probably fix it manually
,
267 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command
);
268 if Pos(AppDir
,Command
)>0 then begin
269 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
270 Msg
:='Line {#__LINE__}: Unable to remove "Git GUI Here" shell extension.';
271 MsgBox(Msg
,mbError
,MB_OK
);
273 // This
is not a critical error
, the user can probably fix it manually
,
279 procedure RefreshProcessList(Sender
:TObject
);
281 Version
:TWindowsVersion
;
282 Modules
:TArrayOfString
;
283 ProcsCloseRequired
,ProcsCloseOptional
:ProcessList
;
286 ManualClosingRequired
:Boolean;
288 GetWindowsVersionEx(Version
);
290 // Use the
Restart Manager API when installing the shell extension on Windows Vista
and above
.
291 if Version
.Major
>=6 then begin
292 SetArrayLength(Modules
,5);
293 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
294 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
295 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
296 Modules
[3]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
297 Modules
[4]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
298 SessionHandle
:=FindProcessesUsingModules(Modules
,Processes
);
300 SetArrayLength(Modules
,3);
301 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
302 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
303 Modules
[2]:=ExpandConstant('{app}\bin\tk85.dll');
304 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
306 SetArrayLength(Modules
,2);
307 Modules
[0]:=ExpandConstant('{app}\git-cheetah\git_shell_ext.dll');
308 Modules
[1]:=ExpandConstant('{app}\git-cheetah\git_shell_ext64.dll');
309 SessionHandle
:=FindProcessesUsingModules(Modules
,ProcsCloseOptional
) or SessionHandle
;
311 // Misuse the
"Restartable" flag
to indicate which processes are required
312 // to be closed before setup can continue
, and which just should be closed
313 // in order
to make changes take effect immediately
.
314 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseOptional
));
315 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
316 Processes
[i
]:=ProcsCloseRequired
[i
];
317 Processes
[i
].Restartable
:=False;
319 for i
:=0 to GetArrayLength(ProcsCloseOptional
)-1 do begin
320 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseOptional
[i
];
321 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
325 ManualClosingRequired
:=False;
327 ProcessesListBox
.Items
.Clear
;
328 if (Sender
=NIL) or (SessionHandle
>0) then begin
329 for i
:=0 to GetArrayLength(Processes
)-1 do begin
330 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
331 if Processes
[i
].Restartable
then begin
332 Caption
:=Caption
+', closing is optional';
334 Caption
:=Caption
+', closing is required';
335 ManualClosingRequired
:=True;
337 Caption
:=Caption
+')';
338 ProcessesListBox
.Items
.Append(Caption
);
342 if ContinueButton
<>NIL then begin
343 ContinueButton
.Enabled
:=not ManualClosingRequired
;
351 procedure InitializeWizard
;
354 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
355 LblOpenSSH
,LblPlink
:TLabel
;
356 PuTTYSessions
:TArrayOfString
;
357 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
362 PrevPageID
:=wpSelectProgramGroup
;
365 * Create a custom page for modifying the environment.
368 PathPage
:=CreateCustomPage(
370 'Adjusting your PATH environment',
371 'How would you like to use Git from the command line?'
373 PrevPageID
:=PathPage
.ID
;
376 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
377 with RdbPath
[GP_BashOnly
] do begin
378 Parent
:=PathPage
.Surface
;
379 Caption
:='Use Git Bash only';
384 Font
.Style
:=[fsBold
];
388 LblGitBash
:=TLabel
.Create(PathPage
);
389 with LblGitBash
do begin
390 Parent
:=PathPage
.Surface
;
392 'This is the most conservative choice if you are concerned about the stability' + #
13 +
393 'of your system. Your PATH will not be modified.';
401 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
402 with RdbPath
[GP_Cmd
] do begin
403 Parent
:=PathPage
.Surface
;
404 Caption
:='Run Git from the Windows Command Prompt';
409 Font
.Style
:=[fsBold
];
412 LblGitCmd
:=TLabel
.Create(PathPage
);
413 with LblGitCmd
do begin
414 Parent
:=PathPage
.Surface
;
416 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
417 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
418 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
426 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
427 with RdbPath
[GP_CmdTools
] do begin
428 Parent
:=PathPage
.Surface
;
429 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
434 Font
.Style
:=[fsBold
];
437 LblGitCmdTools
:=TLabel
.Create(PathPage
);
438 with LblGitCmdTools
do begin
439 Parent
:=PathPage
.Surface
;
440 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
446 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
447 with LblGitCmdToolsWarn
do begin
448 Parent
:=PathPage
.Surface
;
450 'Warning: This will override Windows tools like find.exe and' + #
13 +
451 'sort.exe. Select this option only if you understand the implications.';
457 Font
.Style
:=[fsBold
];
460 // Restore the setting chosen during a previous install
.
461 Data
:=GetPreviousData('Path Option','BashOnly');
462 if Data
='BashOnly' then begin
463 RdbPath
[GP_BashOnly
].Checked
:=True;
464 end else if Data
='Cmd' then begin
465 RdbPath
[GP_Cmd
].Checked
:=True;
466 end else if Data
='CmdTools' then begin
467 RdbPath
[GP_CmdTools
].Checked
:=True;
471 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
472 * if at least one PuTTY session is found in the Registry.
475 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
476 PuTTYPage
:=CreateCustomPage(
478 'Choosing the SSH executable',
479 'Which Secure Shell client program would you like Git to use?'
481 PrevPageID
:=PuTTYPage
.ID
;
484 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
485 with RdbSSH
[GS_OpenSSH
] do begin
486 Parent
:=PuTTYPage
.Surface
;
487 Caption
:='Use OpenSSH';
492 Font
.Style
:=[fsBold
];
496 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
497 with LblOpenSSH
do begin
498 Parent
:=PuTTYPage
.Surface
;
500 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
501 'environment variables will not be modified.';
509 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
510 with RdbSSH
[GS_Plink
] do begin
511 Parent
:=PuTTYPage
.Surface
;
512 Caption
:='Use (Tortoise)Plink';
517 Font
.Style
:=[fsBold
];
520 LblPlink
:=TLabel
.Create(PuTTYPage
);
521 with LblPlink
do begin
522 Parent
:=PuTTYPage
.Surface
;
524 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
525 'to an existing copy of (Tortoise)Plink.exe from the TortoiseGit/SVN/CVS' + #
13 +
526 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
527 'variables will be adjusted to point to the following executable:';
533 EdtPlink
:=TEdit
.Create(PuTTYPage
);
534 with EdtPlink
do begin
535 Parent
:=PuTTYPage
.Surface
;
536 Text:=GetPuTTYLocation
;
537 if not FileExists(Text) then begin
545 BtnPlink
:=TButton
.Create(PuTTYPage
);
546 with BtnPlink
do begin
547 Parent
:=PuTTYPage
.Surface
;
549 OnClick
:=@BrowseForPuTTYFolder
;
556 // Restore the setting chosen during a previous install
.
557 Data
:=GetPreviousData('SSH Option','OpenSSH');
558 if Data
='OpenSSH' then begin
559 RdbSSH
[GS_OpenSSH
].Checked
:=True;
560 end else if Data
='Plink' then begin
561 RdbSSH
[GS_Plink
].Checked
:=True;
568 * Create a custom page for the core.autocrlf setting.
571 CRLFPage
:=CreateCustomPage(
573 'Configuring the line ending conversions',
574 'How should Git treat line endings in text files?'
576 PrevPageID
:=CRLFPage
.ID
;
579 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
580 with RdbCRLF
[GC_CRLFAlways
] do begin
581 Parent
:=CRLFPage
.Surface
;
582 Caption
:='Checkout Windows-style, commit Unix-style line endings';
587 Font
.Style
:=[fsBold
];
591 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
592 with LblCRLFAlways
do begin
593 Parent
:=CRLFPage
.Surface
;
595 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
596 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
597 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
605 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
606 with RdbCRLF
[GC_LFOnly
] do begin
607 Parent
:=CRLFPage
.Surface
;
608 Caption
:='Checkout as-is, commit Unix-style line endings';
613 Font
.Style
:=[fsBold
];
617 LblLFOnly
:=TLabel
.Create(CRLFPage
);
618 with LblLFOnly
do begin
619 Parent
:=CRLFPage
.Surface
;
621 'Git will not perform any conversion when checking out text files. When' + #
13 +
622 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
623 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
631 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
632 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
633 Parent
:=CRLFPage
.Surface
;
634 Caption
:='Checkout as-is, commit as-is';
639 Font
.Style
:=[fsBold
];
643 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
644 with LblCRLFCommitAsIs
do begin
645 Parent
:=CRLFPage
.Surface
;
647 'Git will not perform any conversions when checking out or committing' + #
13 +
648 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
649 'projects ("core.autocrlf" is set to "false").';
656 // Restore the setting chosen during a previous install
.
657 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
658 if Data
='LFOnly' then begin
659 RdbCRLF
[GC_LFOnly
].Checked
:=True;
660 end else if Data
='CRLFAlways' then begin
661 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
662 end else if Data
='CRLFCommitAsIs' then begin
663 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
667 * Create a custom page for finding the processes that lock a module.
670 ProcessesPage
:=CreateCustomPage(
672 'Replacing in-use files',
673 'The following applications use files that need to be replaced, please close them.'
676 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
677 with ProcessesListBox
do begin
678 Parent
:=ProcessesPage
.Surface
;
679 Width
:=ProcessesPage
.SurfaceWidth
;
680 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
683 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
684 with ProcessesRefresh
do begin
686 Width
:=WizardForm
.CancelButton
.Width
;
687 Height
:=WizardForm
.CancelButton
.Height
;
688 Top
:=WizardForm
.CancelButton
.Top
;
689 Left
:=WizardForm
.ClientWidth
-(WizardForm
.CancelButton
.Left
+WizardForm
.CancelButton
.Width
);
691 OnClick
:=@RefreshProcessList
;
694 // This button
is only used by the uninstaller
.
697 // Initially hide the Refresh button
, show it when the process page becomes current
.
698 ProcessesRefresh
.Hide
;
701 function ShouldSkipPage(PageID
:Integer):Boolean;
703 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
704 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
705 RefreshProcessList(NIL);
706 Result
:=(GetArrayLength(Processes
)=0);
712 procedure CurPageChanged(CurPageID
:Integer);
716 if CurPageID
=wpSelectDir
then begin
717 if not IsDirWritable(WizardDirValue
) then begin
718 // If the default directory
is not writable
, choose another default that most likely
is.
719 // This will be checked later again when the user clicks
"Next".
720 WizardForm
.DirEdit
.Text:=ExpandConstant('{userpf}\{#APP_NAME}');
724 // Uncheck the console font option by default
.
725 if CurPageID
=wpSelectComponents
then begin
726 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
727 if WizardForm
.ComponentsList
.ItemCaption
[i
]='{#COMP_CONSOLE_FONT}' then begin
728 WizardForm
.ComponentsList
.Checked
[i
]:=False;
734 // Show the
"Refresh" button only on the processes page
.
735 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
736 ProcessesRefresh
.Show
;
738 ProcessesRefresh
.Hide
;
742 function NextButtonClick(CurPageID
:Integer):Boolean;
745 Version
:TWindowsVersion
;
749 if CurPageID
=wpSelectDir
then begin
750 if not IsDirWritable(WizardDirValue
) then begin
752 'The specified installation directory does not seem to be writable. ' +
753 + 'Please choose another directory or restart setup as a user with sufficient permissions.'
762 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
763 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
764 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
765 if not Result
then begin
766 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
768 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
769 // It would have been nicer
to just disable the
"Next" button
, but the
770 // WizardForm
exports the button just
read-only
.
771 for i
:=0 to GetArrayLength(Processes
)-1 do begin
772 if not Processes
[i
].Restartable
then begin
773 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
779 Result
:=(GetArrayLength(Processes
)=0);
781 if not Result
then begin
782 GetWindowsVersionEx(Version
);
783 if Version
.Major
>=6 then begin
785 'If you continue without closing the listed applications they will be closed and restarted automatically.' + #
13 + #
13 +
786 'Are you sure you want to continue?',
792 'If you continue without closing the listed applications you will need to log off and on again before changes take effect.' + #
13 + #
13 +
793 'Are you sure you want to continue anyway?',
802 procedure CurStepChanged(CurStep
:TSetupStep
);
804 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
805 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
811 if CurStep
=ssInstall
then begin
812 // Shutdown locking processes just before the actual installation starts
.
813 if SessionHandle
>0 then try
814 RmShutdown(SessionHandle
,RmShutdownOnlyRegistered
,0);
816 Log('Line {#__LINE__}: RmShutdown not supported.');
822 // Make sure the code below
is only executed just after the actual installation finishes
.
823 if CurStep
<>ssPostInstall
then begin
827 AppDir
:=ExpandConstant('{app}');
830 Bind the imported function addresses
834 DllPath
:=ExpandConstant('{app}\bin;{sys}');
836 // Load the list
of images from a
text file.
837 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
838 if LoadStringsFromFile(FileName
,ImageNames
) then begin
839 Count
:=GetArrayLength(ImageNames
)-1;
840 for i
:=0 to Count
do begin
841 FileName
:=AppDir
+'\'+ImageNames[i];
842 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
843 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
848 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
855 // Load the built-ins from a text file.
856 FileName:=AppDir+'\
{#APP_BUILTINS}';
857 if LoadStringsFromFile(FileName,BuiltIns) then begin
858 Count:=GetArrayLength(BuiltIns)-1;
860 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
861 for i:=0 to Count do begin
862 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
863 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
864 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
868 // Create built
-ins
as aliases
for git
.exe
.
869 for i
:=0 to Count
do begin
870 FileName
:=AppDir
+'\'+BuiltIns[i];
872 // Delete any existing built-in.
873 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
874 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
879 // This will throw an exception on pre-Win2k systems.
880 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
883 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
886 if not LinkCreated then begin
887 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
888 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
889 // This is not a critical error, Git could basically be used without the
890 // aliases for built-ins, so we continue.
895 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
896 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
898 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
899 FileName:=AppDir+'\bin
\'+FindRec
.name
;
900 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
901 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
904 until not FindNext(FindRec
);
908 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
909 MsgBox(Msg
,mbError
,MB_OK
);
911 // This
is not a critical error
, Git could basically be used without the
912 // aliases
for built
-ins
, so we continue
.
919 if RdbCRLF
[GC_LFOnly
].checked
then begin
920 Cmd
:='core.autocrlf input';
921 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
922 Cmd
:='core.autocrlf true';
924 Cmd
:='core.autocrlf false';
926 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
927 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
928 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
929 MsgBox(Msg
,mbError
,MB_OK
);
931 // This
is not a critical error
, the user can probably fix it manually
,
936 Modify the environment
938 This must happen no later than ssPostInstall to make
939 "ChangesEnvironment=yes" not happend before the change!
942 FileName
:=AppDir
+'\setup.ini';
944 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
945 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
946 if (GetArrayLength(EnvSSH
)=1) and
947 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
948 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
949 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
950 MsgBox(Msg
,mbError
,MB_OK
);
952 // This
is not a critical error
, the user can probably fix it manually
,
957 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
958 if (GetArrayLength(EnvSSH
)=1) and
959 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
960 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
961 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
962 MsgBox(Msg
,mbError
,MB_OK
);
964 // This
is not a critical error
, the user can probably fix it manually
,
969 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
970 SetArrayLength(EnvSSH
,1);
971 EnvSSH
[0]:=EdtPlink
.Text;
973 // Set GIT_SSH
as specified by the user
.
974 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
975 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
976 MsgBox(Msg
,mbError
,MB_OK
);
978 // This
is not a critical error
, the user can probably fix it manually
,
982 // Mark that we have changed GIT_SSH by writing its value
to a
file.
983 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
984 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
985 MsgBox(Msg
,mbError
,MB_OK
);
987 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
991 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
992 Msg
:='Line {#__LINE__}: Unable to set the SVN_SSH environment variable.';
993 MsgBox(Msg
,mbError
,MB_OK
);
995 // This
is not a critical error
, the user can probably fix it manually
,
999 // Mark that we have changed SVN_SSH by writing its value
to a
file.
1000 if not SetIniString('Environment','SVN_SSH',EnvSSH
[0],FileName
) then begin
1001 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1002 MsgBox(Msg
,mbError
,MB_OK
);
1004 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1009 // Get the current user
's directories in PATH.
1010 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
1012 // First, remove the installation directory from PATH in any case.
1013 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1014 if Pos(AppDir+'\',EnvPath
[i
]+'\')=1 then begin
1019 // Delete HOME if a previous installation modified it.
1020 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1021 if (GetArrayLength(EnvHome)=1) and
1022 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment
','HOME
','',FileName))=0) then begin
1023 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,[]) then begin
1024 Msg:='Line
{#__LINE__}: Unable
to reset HOME prior
to install
.';
1025 MsgBox(Msg,mbError,MB_OK);
1027 // This is not a critical error, the user can probably fix it manually,
1032 // Modify the PATH variable as requested by the user.
1033 if RdbPath[GP_Cmd].Checked or RdbPath[GP_CmdTools].Checked then begin
1034 i:=GetArrayLength(EnvPath);
1035 SetArrayLength(EnvPath,i+1);
1037 // List \cmd before \bin so \cmd has higher priority and programs in
1038 // there will be called in favor of those in \bin.
1039 EnvPath[i]:=AppDir+'\cmd
';
1041 if RdbPath[GP_CmdTools].Checked then begin
1042 SetArrayLength(EnvPath,i+2);
1043 EnvPath[i+1]:=AppDir+'\bin
';
1045 // Set HOME for the Windows Command Prompt, but only if it has not been set manually before.
1046 EnvHome:=GetEnvStrings('HOME
',IsAdminLoggedOn);
1047 i:=GetArrayLength(EnvHome);
1048 if (i=0) or ((i=1) and (Length(EnvHome[0])=0)) then begin
1049 SetArrayLength(EnvHome,1);
1050 EnvHome[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1051 if not SetEnvStrings('HOME
',IsAdminLoggedOn,True,EnvHome) then begin
1052 Msg:='Line
{#__LINE__}: Unable
to set the HOME environment variable
.';
1053 MsgBox(Msg,mbError,MB_OK);
1055 // This is not a critical error, the user can probably fix it manually,
1059 // Mark that we have changed HOME.
1060 if not SetIniString('Environment
','HOME
',EnvHome[0],FileName) then begin
1061 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
1062 MsgBox(Msg,mbError,MB_OK);
1064 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
1071 // Set the current user's PATH directories
.
1072 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
1073 Msg
:='Line {#__LINE__}: Unable to set the PATH environment variable.';
1074 MsgBox(Msg
,mbError
,MB_OK
);
1076 // This
is not a critical error
, the user can probably fix it manually
,
1081 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder" toggle
1084 Cmd
:=ExpandConstant('{syswow64}\cmd.exe');
1085 TempName
:='/c ""'+AppDir
+'\bin\sh.exe" --login -i"';
1086 FileName
:=AppDir
+'\etc\git.ico';
1088 if IsComponentSelected('icons\quicklaunch') then begin
1090 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1094 , '%HOMEDRIVE%%HOMEPATH%'
1100 if IsComponentSelected('icons\desktop') then begin
1102 GetShellFolder('desktop')+'\Git Bash.lnk'
1106 , '%HOMEDRIVE%%HOMEPATH%'
1113 // Create a special shortcut that does
not set a working
directory (Note
: Since Inno Setup
5.3.11,
1114 // passing an empty WorkingDir gets replaced
with {sys}, so use
'.' instead
).
1115 // This shortcut
is used by
"Git Bash.vbs", which
in turn
is run by the
"Git Bash Here" shell extension
.
1117 AppDir
+'\Git Bash.lnk'
1128 Create the Windows Explorer integrations
1131 if IsAdminLoggedOn
then begin
1132 RootKey
:=HKEY_LOCAL_MACHINE
;
1134 RootKey
:=HKEY_CURRENT_USER
;
1137 if IsComponentSelected('ext\reg\shellhere') then begin
1138 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
1139 (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','','"'+ExpandConstant('{syswow64}')+'\wscript" "'+AppDir
+'\Git Bash.vbs" "%1"')) then begin
1140 Msg
:='Line {#__LINE__}: Unable to create "Git Bash Here" shell extension.';
1141 MsgBox(Msg
,mbError
,MB_OK
);
1143 // This
is not a critical error
, the user can probably fix it manually
,
1148 if IsComponentSelected('ext\reg\guihere') then begin
1149 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
1150 (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
1151 Msg
:='Line {#__LINE__}: Unable to create "Git GUI Here" shell extension.';
1152 MsgBox(Msg
,mbError
,MB_OK
);
1154 // This
is not a critical error
, the user can probably fix it manually
,
1159 // It
is either the Registry
-based context menu entries
, or the shell extension
.
1160 if IsComponentSelected('ext\cheetah') then begin
1161 DeleteContextMenuEntries
;
1163 if isWin64
then begin
1164 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1166 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1168 if not ReplaceInUseFile(FileName
,FileName
+'.new',True) then begin
1169 Log('Line {#__LINE__}: Replacing file "'+FileName
+'" failed.');
1174 Restart any processes that were shut down via the Restart Manager
1177 if SessionHandle
>0 then try
1178 RmRestart(SessionHandle
,0,0);
1179 RmEndSession(SessionHandle
);
1181 Log('Line {#__LINE__}: RmRestart not supported.');
1185 procedure RegisterPreviousData(PreviousDataKey
:Integer);
1189 // Git Path options
.
1191 if RdbPath
[GP_BashOnly
].Checked
then begin
1193 end else if RdbPath
[GP_Cmd
].Checked
then begin
1195 end else if RdbPath
[GP_CmdTools
].Checked
then begin
1198 SetPreviousData(PreviousDataKey
,'Path Option',Data
);
1202 if (PuTTYPage
=NIL) or RdbSSH
[GS_OpenSSH
].Checked
then begin
1204 end else if RdbSSH
[GS_Plink
].Checked
then begin
1207 SetPreviousData(PreviousDataKey
,'SSH Option',Data
);
1209 // Line ending conversion options
.
1211 if RdbCRLF
[GC_LFOnly
].Checked
then begin
1213 end else if RdbCRLF
[GC_CRLFAlways
].Checked
then begin
1215 end else if RdbCRLF
[GC_CRLFCommitAsIs
].Checked
then begin
1216 Data
:='CRLFCommitAsIs';
1218 SetPreviousData(PreviousDataKey
,'CRLF Option',Data
);
1225 function InitializeUninstall
:Boolean;
1229 ExitButton
,RefreshButton
:TButton
;
1233 Form
:=CreateCustomForm
;
1235 Form
.Caption
:='Git Uninstall: Removing in-use files';
1236 Form
.ClientWidth
:=ScaleX(500);
1237 Form
.ClientHeight
:=ScaleY(256);
1240 Info
:=TLabel
.Create(Form
);
1246 Caption
:='The following applications use files that need to be removed, please close them.';
1249 ContinueButton
:=TButton
.Create(Form
);
1250 with ContinueButton
do begin
1252 Left
:=Form
.ClientWidth
-ScaleX(75+10);
1253 Top
:=Form
.ClientHeight
-ScaleY(23+10);
1256 Caption
:='Continue';
1260 ExitButton
:=TButton
.Create(Form
);
1261 with ExitButton
do begin
1263 Left
:=ContinueButton
.Left
-ScaleX(75+6);
1264 Top
:=ContinueButton
.Top
;
1268 ModalResult
:=mrCancel
;
1272 RefreshButton
:=TButton
.Create(Form
);
1273 with RefreshButton
do begin
1276 Top
:=ExitButton
.Top
;
1280 OnClick
:=@RefreshProcessList
;
1283 ProcessesListBox
:=TListBox
.Create(Form
);
1284 with ProcessesListBox
do begin
1287 Top
:=Info
.Top
+Info
.Height
+11;
1288 Width
:=Form
.ClientWidth
-ScaleX(11*2);
1289 Height
:=ContinueButton
.Top
-ScaleY(11*4);
1292 Form
.ActiveControl
:=ContinueButton
;
1294 RefreshProcessList(NIL);
1295 if GetArrayLength(Processes
)>0 then begin
1296 // Now that these dialogs are going
to be shown
, we should probably
1297 // disable the
"Are you sure to remove Git?" confirmation dialog
, but
1298 // unfortunately that
is not possible
with Inno Setup currently
.
1299 Result
:=(Form
.ShowModal()=mrOk
);
1301 // Note
: The number
of processes might have changed during a refresh
.
1302 if Result
and (GetArrayLength(Processes
)>0) then begin
1304 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #
13 + #
13 +
1305 'Are you sure you want to continue anyway?',
1318 // Even though the name
of this
function suggests otherwise most
of the
1319 // code below
is only executed right before the actual uninstallation
.
1320 // This happens because
of the
if-guard right
in the beginning
of this
1322 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
1324 AppDir
,FileName
,Msg
:String;
1325 EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
1328 if CurUninstallStep
<>usUninstall
then begin
1332 // Reset the console
font (the FontType
is reset
in the Registry section
).
1333 if IsComponentInstalled('consolefont') then begin
1334 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation
,MB_YESNO
)=IDYES
then begin
1335 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontFamily',0);
1336 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontSize',0);
1337 RegWriteDWordValue(HKEY_CURRENT_USER
,'Console','FontWeight',0);
1342 Modify the environment
1344 This must happen no later than usUninstall to make
1345 "ChangesEnvironment=yes" not happend before the change!
1348 AppDir
:=ExpandConstant('{app}');
1349 FileName
:=AppDir
+'\setup.ini';
1351 // Delete the current user
's GIT_SSH and SVN_SSH if we set it.
1352 EnvSSH:=GetEnvStrings('GIT_SSH
',IsAdminLoggedOn);
1353 if (GetArrayLength(EnvSSH)=1) and
1354 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','GIT_SSH
','',FileName))=0) then begin
1355 if not SetEnvStrings('GIT_SSH
',IsAdminLoggedOn,True,[]) then begin
1356 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to GIT_SSH
.';
1357 MsgBox(Msg,mbError,MB_OK);
1359 // This is not a critical error, the user can probably fix it manually,
1364 EnvSSH:=GetEnvStrings('SVN_SSH
',IsAdminLoggedOn);
1365 if (GetArrayLength(EnvSSH)=1) and
1366 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment
','SVN_SSH
','',FileName))=0) then begin
1367 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,[]) then begin
1368 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to SVN_SSH
.';
1369 MsgBox(Msg,mbError,MB_OK);
1371 // This is not a critical error, the user can probably fix it manually,
1376 // Get the current user's directories
in PATH
.
1377 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
1379 // Remove the installation directory from PATH
in any
case, even
if it
1380 // was
not added by the installer
.
1381 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
1382 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
1387 // Reset the current user
's directories in PATH.
1388 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1389 Msg:='Line
{#__LINE__}: Unable
to revert any possible changes
to PATH
.';
1390 MsgBox(Msg,mbError,MB_OK);
1392 // This is not a critical error, the user can probably fix it manually,
1396 // Reset the current user's HOME
if we modified it
.
1397 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1398 if (GetArrayLength(EnvHome
)=1) and
1399 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
1400 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
1401 Msg
:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1402 MsgBox(Msg
,mbError
,MB_OK
);
1404 // This
is not a critical error
, the user can probably fix it manually
,
1409 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
1410 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'".';
1411 MsgBox(Msg
,mbError
,MB_OK
);
1413 // This
is not a critical error
, the user can probably fix it manually
,
1418 Delete the Windows Explorer integrations
1421 DeleteContextMenuEntries
;
1423 if isWin64
then begin
1424 FileName
:=AppDir
+'\git-cheetah\git_shell_ext64.dll';
1426 FileName
:=AppDir
+'\git-cheetah\git_shell_ext.dll';
1428 if FileExists(FileName
) then begin
1429 if not UnregisterServer(Is64BitInstallMode
,FileName
,False) then begin
1430 Msg
:='Line {#__LINE__}: Unable to unregister file "'+FileName
+'". Please do it manually by running "regsvr32 /u '+ExtractFileName(FileName
)+'".';
1431 MsgBox(Msg
,mbError
,MB_OK
);
1435 if not DeleteFile(FileName
) then begin
1436 Msg
:='Line {#__LINE__}: Unable to delete file "'+FileName
+'". Please do it manually after logging off and on again.';
1437 MsgBox(Msg
,mbError
,MB_OK
);