2 #define APP_VERSION
'%APPVERSION%'
3 #define APP_URL
'http://msysgit.googlecode.com/'
4 #define APP_BUILTINS
'etc\fileList-builtins.txt'
5 #define APP_BINDIMAGE
'etc\fileList-bindimage.txt'
7 #define COMP_CONSOLE_FONT
'Use a TrueType font in all console windows (not only for Git Bash)'
9 #define DROP_HANDLER_GUID
'{{86C86720-42A0-1069-A2E8-08002B30309D}}'
13 Compression
=lzma2
/ultra
14 LZMAUseSeparateProcess
=yes
15 OutputBaseFilename
={#APP_NAME+'-'+APP_VERSION}
16 OutputDir
={#GetEnv('USERPROFILE')}
19 ; Uncomment the line below to be able to compile the script from within the IDE.
20 ;SourceDir={#GetEnv('TEMP')}\WinGit
25 AppPublisherURL
={#APP_URL}
26 AppVersion
={#APP_VERSION}
27 ChangesEnvironment
=yes
28 DefaultDirName
={pf}\
{#APP_NAME}
29 DefaultGroupName
={#APP_NAME}
31 InfoBeforeFile
=gpl
-2.0.rtf
32 PrivilegesRequired
=none
33 UninstallDisplayIcon
=etc\git
.ico
36 SetupIconFile
=etc\git
.ico
37 WizardImageBackColor
=clWhite
39 WizardImageFile
=git
.bmp
40 WizardSmallImageFile
=gitsmall
.bmp
43 ; Define a dummy type to avoid getting the default ones.
44 Name
: custom
; Description
: Custom installation
; Flags
: iscustom
47 Name
: icons
; Description
: Additional icons
; Types
: custom
48 Name
: icons\quicklaunch
; Description
: In the Quick Launch
; Types
: custom
49 Name
: icons\desktop
; Description
: On the Desktop
; Types
: custom
50 Name
: ext
; Description
: Windows Explorer integration
; Types
: custom
51 Name
: ext
\reg
; Description
: Context menu entries
; Flags
: exclusive; Types
: custom
52 Name
: ext
\reg\shellhere
; Description
: Git Bash Here
; Types
: custom
53 Name
: ext
\reg\guihere
; Description
: Git GUI Here
; Types
: custom
54 Name
: ext\cheetah
; Description
: git
-cheetah shell
extension (32-bit only
); Flags
: exclusive; Types
: custom
55 Name
: assoc
; Description
: Associate
.git
* configuration
files with the default
text editor
; Types
: custom
56 Name
: assoc_sh
; Description
: Associate
.sh
files to be run
with Bash
; Types
: custom
57 Name
: consolefont
; Description
: {#COMP_CONSOLE_FONT}; Types
: custom
60 ; Install files that might be in use during setup under a different name.
61 Source
: git
-cheetah\git_shell_ext
.dll
; DestDir
: {app}\git
-cheetah
; DestName
: git_shell_ext
.dll
.new
; Flags
: replacesameversion
63 Source
: *; DestDir
: {app}; Excludes
: \
*.bmp
, gpl
-2.0.rtf
, \
*.iss
, \tmp
.*, \bin\
*install
*, \git
-cheetah\git_shell_ext
.dll
; Flags
: recursesubdirs replacesameversion
64 Source
: ReleaseNotes
.rtf
; DestDir
: {app}; Flags
: isreadme replacesameversion
67 Name
: {group}\Git GUI
; Filename
: {app}\bin\wish
.exe
; Parameters
: """{app}\libexec\git-core\git-gui"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
68 Name
: {group}\Git Bash
; Filename
: {syswow64}\cmd
.exe
; Parameters
: "/c """"{app}\bin\sh.exe"" --login -i"""; WorkingDir
: %HOMEDRIVE
%%HOMEPATH
%; IconFilename
: {app}\etc\git
.ico
71 BeveledLabel
={#APP_URL}
72 SetupAppTitle
={#APP_NAME} Setup
73 SetupWindowTitle
={#APP_NAME} Setup
76 ; There is no "Console" key in HKLM.
77 Root
: HKCU
; Subkey
: Console
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: uninsclearvalue; Components
: consolefont
78 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Components
: consolefont
79 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Components
: consolefont
80 Root
: HKCU
; Subkey
: Console
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Components
: consolefont
82 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: string; ValueName
: FaceName
; ValueData
: Lucida Console
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
83 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontFamily
; ValueData
: $00000036; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
84 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontSize
; ValueData
: $000e0000; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
85 Root
: HKCU
; Subkey
: Console\Git Bash
; ValueType
: dword
; ValueName
: FontWeight
; ValueData
: $00000190; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty
87 ; Note that we write the Registry values below either to HKLM or to HKCU depending on whether the user running the installer
88 ; is a member of the local Administrators group or not (see the "Check" argument).
90 ; File associations for configuration files that may be contained in a repository (so this does not include ".gitconfig").
91 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
92 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
93 Root
: HKLM
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
94 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
95 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
96 Root
: HKCU
; Subkey
: Software\Classes\
.gitattributes
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
98 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
99 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
100 Root
: HKLM
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
101 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
102 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
103 Root
: HKCU
; Subkey
: Software\Classes\
.gitignore
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
105 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
106 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
107 Root
: HKLM
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: IsAdminLoggedOn
; Components
: assoc
108 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueData
: txtfile
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
109 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: Content
Type; ValueData
: text/plain
; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
110 Root
: HKCU
; Subkey
: Software\Classes\
.gitmodules
; ValueType
: string; ValueName
: PerceivedType
; ValueData
: text; Flags
: createvalueifdoesntexist uninsdeletevalue uninsdeletekeyifempty; Check
: not IsAdminLoggedOn
; Components
: assoc
112 ; Associate .sh extension with sh.exe so those files are double-clickable,
113 ; startable from cmd.exe, and when files are dropped on them they are passed
114 ; as arguments to the script.
116 ; Install under HKEY_LOCAL_MACHINE if an administrator is installing.
117 Root
: HKLM
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
118 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
119 Root
: HKLM
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: """{app}\bin\sh.exe"" ""--login"" ""%1"" %*"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: IsAdminLoggedOn
; Components
: assoc_sh
120 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
121 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
123 ; Install under HKEY_CURRENT_USER if a non-administrator is installing.
124 Root
: HKCU
; Subkey
: Software\Classes\
.sh
; ValueType
: string; ValueData
: sh_auto_file
; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
125 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file
; ValueType
: string; ValueData
: "Shell Script"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
126 Root
: HKCU
; Subkey
: Software\Classes\sh_auto_file\shell\open\command
; ValueType
: string; ValueData
: """{app}\bin\sh.exe"" ""--login"" ""%1"" %*"; Flags
: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue; Check
: not IsAdminLoggedOn
; Components
: assoc_sh
127 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
128 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
131 ; Delete the built-ins.
132 Type: files; Name
: {app}\bin\git
-*.exe
133 Type: files; Name
: {app}\libexec\git
-core\git
-*.exe
134 Type: files; Name
: {app}\libexec\git
-core\git
.exe
136 ; Delete any (temporary) git-cheetah files.
137 Type: files; Name
: {app}\git
-cheetah\
*.*
139 ; Delete any manually created shortcuts.
140 Type: files; Name
: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash
.lnk
141 Type: files; Name
: {code:GetShellFolder|desktop}\Git Bash
.lnk
142 Type: files; Name
: {app}\Git Bash
.lnk
144 ; Delete a home directory inside the msysGit directory.
145 Type: dirifempty; Name
: {app}\home\
{username}
146 Type: dirifempty; Name
: {app}\home
149 #include
"helpers.inc.iss"
150 #include
"putty.inc.iss"
151 #include
"modules.inc.iss"
153 function CreateHardLink(lpFileName
,lpExistingFileName
:String;lpSecurityAttributes
:Integer):Boolean;
155 external 'CreateHardLinkW@Kernel32.dll stdcall delayload setuponly';
157 external 'CreateHardLinkA@Kernel32.dll stdcall delayload setuponly';
160 function CreateSymbolicLink(lpSymlinkFileName
,lpTargetFileName
:String;dwFlags
:DWORD
):Boolean;
162 external 'CreateSymbolicLinkW@Kernel32.dll stdcall delayload setuponly';
164 external 'CreateSymbolicLinkA@Kernel32.dll stdcall delayload setuponly';
167 function BindImageEx(Flags
:DWORD
;ImageName
,DllPath
,SymbolPath
:AnsiString
;StatusRoutine
:Integer):Boolean;
168 external 'BindImageEx@Imagehlp.dll stdcall delayload setuponly';
180 // Git line ending conversion options
.
183 GC_CRLFCommitAsIs
= 3;
185 // BindImageEx API constants
.
186 BIND_NO_BOUND_IMPORTS
= $00000001;
187 BIND_NO_UPDATE
= $00000002;
188 BIND_ALL_IMAGES
= $00000004;
189 BIND_CACHE_IMPORT_DLLS
= $00000008;
192 // Wizard page
and variables
for the Path options
.
193 PathPage
:TWizardPage
;
194 RdbPath
:array[GP_BashOnly
..GP_CmdTools
] of TRadioButton
;
196 // Wizard page
and variables
for the SSH options
.
197 PuTTYPage
:TWizardPage
;
198 RdbSSH
:array[GS_OpenSSH
..GS_Plink
] of TRadioButton
;
201 // Wizard page
and variables
for the line ending conversion options
.
202 CRLFPage
:TWizardPage
;
203 RdbCRLF
:array[GC_LFOnly
..GC_CRLFCommitAsIs
] of TRadioButton
;
205 // Wizard page
and variables
for the processes page
.
206 Processes
:ProcessList
;
207 ProcessesPage
:TWizardPage
;
208 ProcessesListBox
:TListBox
;
209 ProcessesRefresh
,ContinueButton
:TButton
;
211 procedure BrowseForPuTTYFolder(Sender
:TObject
);
215 Path
:=ExtractFilePath(EdtPlink
.Text);
216 BrowseForFolder('Please select the PuTTY folder:',Path
,False);
217 if FileExists(Path
+'\TortoisePlink.exe') then begin
218 EdtPlink
.Text:=Path
+'\TortoisePlink.exe';
219 RdbSSH
[GS_Plink
].Checked
:=True;
220 end else if FileExists(Path
+'\plink.exe') then begin
221 EdtPlink
.Text:=Path
+'\plink.exe';
222 RdbSSH
[GS_Plink
].Checked
:=True;
224 MsgBox('Please enter a valid path to "TortoisePlink.exe" or "plink.exe".',mbError
,MB_OK
);
228 procedure DeleteContextMenuEntries
;
230 AppDir
,Command
,Msg
:String;
233 AppDir
:=ExpandConstant('{app}');
235 if IsAdminLoggedOn
then begin
236 RootKey
:=HKEY_LOCAL_MACHINE
;
238 RootKey
:=HKEY_CURRENT_USER
;
242 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell\command','',Command
);
243 if Pos(AppDir
,Command
)>0 then begin
244 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_shell') then begin
245 Msg
:='Line {#__LINE__}: Unable to remove "Git Bash Here" shell extension.';
246 MsgBox(Msg
,mbError
,MB_OK
);
248 // This
is not a critical error
, the user can probably fix it manually
,
254 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui\command','',Command
);
255 if Pos(AppDir
,Command
)>0 then begin
256 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_gui') then begin
257 Msg
:='Line {#__LINE__}: Unable to remove "Git GUI Here" shell extension.';
258 MsgBox(Msg
,mbError
,MB_OK
);
260 // This
is not a critical error
, the user can probably fix it manually
,
266 procedure RefreshProcessList(Sender
:TObject
);
268 Modules
:TArrayOfString
;
269 ProcsCloseRequired
,ProcsCloseRestart
:ProcessList
;
274 SetArrayLength(Modules
,2);
275 Modules
[0]:=ExpandConstant('{app}\bin\msys-1.0.dll');
276 Modules
[1]:=ExpandConstant('{app}\bin\tcl85.dll');
277 Found
:=FindProcessesUsingModules(Modules
,ProcsCloseRequired
);
279 Found
:=FindProcessesUsingModule(ExpandConstant('{app}\git-cheetah\git_shell_ext.dll'),ProcsCloseRestart
) or Found
;
281 // Misuse the
"Restartable" flag
to indicate which processes are required
282 // to be closed before setup can continue
, and which just should be closed
283 // in order
to make changes take effect immediately
.
284 SetArrayLength(Processes
,GetArrayLength(ProcsCloseRequired
)+GetArrayLength(ProcsCloseRestart
));
285 for i
:=0 to GetArrayLength(ProcsCloseRequired
)-1 do begin
286 Processes
[i
]:=ProcsCloseRequired
[i
];
287 Processes
[i
].Restartable
:=False;
289 for i
:=0 to GetArrayLength(ProcsCloseRestart
)-1 do begin
290 Processes
[GetArrayLength(ProcsCloseRequired
)+i
]:=ProcsCloseRestart
[i
];
291 Processes
[GetArrayLength(ProcsCloseRequired
)+i
].Restartable
:=True;
294 ProcessesListBox
.Items
.Clear
;
295 if (Sender
=NIL) or Found
then begin
296 for i
:=0 to GetArrayLength(Processes
)-1 do begin
297 Caption
:=Processes
[i
].Name
+' (PID '+IntToStr(Processes
[i
].ID
);
298 if not Processes
[i
].Restartable
then begin
299 Caption
:=Caption
+', closing is required';
301 Caption
:=Caption
+')';
302 ProcessesListBox
.Items
.Append(Caption
);
306 if ContinueButton
<>NIL then begin
307 ContinueButton
.Enabled
:=(GetArrayLength(ProcsCloseRequired
)=0);
315 procedure InitializeWizard
;
317 i
,PrevPageID
:Integer;
318 LblGitBash
,LblGitCmd
,LblGitCmdTools
,LblGitCmdToolsWarn
:TLabel
;
319 LblOpenSSH
,LblPlink
:TLabel
;
320 PuTTYSessions
:TArrayOfString
;
321 LblLFOnly
,LblCRLFAlways
,LblCRLFCommitAsIs
:TLabel
;
325 // Until we have a
64-bit version
of git
-cheetah
, disable it on
64-bit Windows
.
326 if isWin64
then begin
327 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
328 Data
:=LowerCase(WizardForm
.ComponentsList
.ItemCaption
[i
]);
329 if Pos('context',Data
)>0 then begin
330 // Select the Registry
-based context menu entries
.
331 WizardForm
.ComponentsList
.Checked
[i
]:=True;
332 end else if Pos('cheetah',Data
)>0 then begin
333 // Disable the git
-cheetah shell extension
.
334 WizardForm
.ComponentsList
.ItemEnabled
[i
]:=False;
339 PrevPageID
:=wpSelectProgramGroup
;
342 * Create a custom page for modifying the environment.
345 PathPage
:=CreateCustomPage(
347 'Adjusting your PATH environment',
348 'How would you like to use Git from the command line?'
350 PrevPageID
:=PathPage
.ID
;
353 RdbPath
[GP_BashOnly
]:=TRadioButton
.Create(PathPage
);
354 with RdbPath
[GP_BashOnly
] do begin
355 Parent
:=PathPage
.Surface
;
356 Caption
:='Use Git Bash only';
361 Font
.Style
:=[fsBold
];
365 LblGitBash
:=TLabel
.Create(PathPage
);
366 with LblGitBash
do begin
367 Parent
:=PathPage
.Surface
;
369 'This is the most conservative choice if you are concerned about the stability' + #
13 +
370 'of your system. Your PATH will not be modified.';
378 RdbPath
[GP_Cmd
]:=TRadioButton
.Create(PathPage
);
379 with RdbPath
[GP_Cmd
] do begin
380 Parent
:=PathPage
.Surface
;
381 Caption
:='Run Git from the Windows Command Prompt';
386 Font
.Style
:=[fsBold
];
389 LblGitCmd
:=TLabel
.Create(PathPage
);
390 with LblGitCmd
do begin
391 Parent
:=PathPage
.Surface
;
393 'This option is considered safe and no conflicts with other tools are known.' + #
13 +
394 'Only Git will be added to your PATH. Use this option if you want to use Git' + #
13 +
395 'from a Cygwin Prompt (make sure to not have Cygwin''s Git installed).';
403 RdbPath
[GP_CmdTools
]:=TRadioButton
.Create(PathPage
);
404 with RdbPath
[GP_CmdTools
] do begin
405 Parent
:=PathPage
.Surface
;
406 Caption
:='Run Git and included Unix tools from the Windows Command Prompt';
411 Font
.Style
:=[fsBold
];
414 LblGitCmdTools
:=TLabel
.Create(PathPage
);
415 with LblGitCmdTools
do begin
416 Parent
:=PathPage
.Surface
;
417 Caption
:='Both Git and its accompanying Unix tools will be added to your PATH.';
423 LblGitCmdToolsWarn
:=TLabel
.Create(PathPage
);
424 with LblGitCmdToolsWarn
do begin
425 Parent
:=PathPage
.Surface
;
427 'Warning: This will override Windows tools like find.exe and' + #
13 +
428 'sort.exe. Select this option only if you understand the implications.';
434 Font
.Style
:=[fsBold
];
437 // Restore the setting chosen during a previous install
.
438 Data
:=GetPreviousData('Path Option','BashOnly');
439 if Data
='BashOnly' then begin
440 RdbPath
[GP_BashOnly
].Checked
:=True;
441 end else if Data
='Cmd' then begin
442 RdbPath
[GP_Cmd
].Checked
:=True;
443 end else if Data
='CmdTools' then begin
444 RdbPath
[GP_CmdTools
].Checked
:=True;
448 * Create a custom page for using (Tortoise)Plink instead of OpenSSH
449 * if at least one PuTTY session is found in the Registry.
452 if RegGetSubkeyNames(HKEY_CURRENT_USER
,'Software\SimonTatham\PuTTY\Sessions',PuTTYSessions
) and (GetArrayLength(PuTTYSessions
)>0) then begin
453 PuTTYPage
:=CreateCustomPage(
455 'Choosing the SSH executable',
456 'Which Secure Shell client program would you like Git to use?'
458 PrevPageID
:=PuTTYPage
.ID
;
461 RdbSSH
[GS_OpenSSH
]:=TRadioButton
.Create(PuTTYPage
);
462 with RdbSSH
[GS_OpenSSH
] do begin
463 Parent
:=PuTTYPage
.Surface
;
464 Caption
:='Use OpenSSH';
469 Font
.Style
:=[fsBold
];
473 LblOpenSSH
:=TLabel
.Create(PuTTYPage
);
474 with LblOpenSSH
do begin
475 Parent
:=PuTTYPage
.Surface
;
477 'This uses ssh.exe that comes with Git. The GIT_SSH and SVN_SSH' + #
13 +
478 'environment variables will not be modified.';
486 RdbSSH
[GS_Plink
]:=TRadioButton
.Create(PuTTYPage
);
487 with RdbSSH
[GS_Plink
] do begin
488 Parent
:=PuTTYPage
.Surface
;
489 Caption
:='Use (Tortoise)Plink';
494 Font
.Style
:=[fsBold
];
497 LblPlink
:=TLabel
.Create(PuTTYPage
);
498 with LblPlink
do begin
499 Parent
:=PuTTYPage
.Surface
;
501 'PuTTY sessions were found in your Registry. You may specify the path' + #
13 +
502 'to an existing copy of (Tortoise)Plink.exe from the TortoiseSVN/CVS' + #
13 +
503 'or PuTTY applications. The GIT_SSH and SVN_SSH environment' + #
13 +
504 'variables will be adjusted to point to the following executable:';
510 EdtPlink
:=TEdit
.Create(PuTTYPage
);
511 with EdtPlink
do begin
512 Parent
:=PuTTYPage
.Surface
;
513 Text:=GetPuTTYLocation
;
514 if not FileExists(Text) then begin
522 BtnPlink
:=TButton
.Create(PuTTYPage
);
523 with BtnPlink
do begin
524 Parent
:=PuTTYPage
.Surface
;
526 OnClick
:=@BrowseForPuTTYFolder
;
533 // Restore the setting chosen during a previous install
.
534 Data
:=GetPreviousData('SSH Option','OpenSSH');
535 if Data
='OpenSSH' then begin
536 RdbSSH
[GS_OpenSSH
].Checked
:=True;
537 end else if Data
='Plink' then begin
538 RdbSSH
[GS_Plink
].Checked
:=True;
545 * Create a custom page for the core.autocrlf setting.
548 CRLFPage
:=CreateCustomPage(
550 'Configuring the line ending conversions',
551 'How should Git treat line endings in text files?'
553 PrevPageID
:=CRLFPage
.ID
;
556 RdbCRLF
[GC_CRLFAlways
]:=TRadioButton
.Create(CRLFPage
);
557 with RdbCRLF
[GC_CRLFAlways
] do begin
558 Parent
:=CRLFPage
.Surface
;
559 Caption
:='Checkout Windows-style, commit Unix-style line endings';
564 Font
.Style
:=[fsBold
];
568 LblCRLFAlways
:=TLabel
.Create(CRLFPage
);
569 with LblCRLFAlways
do begin
570 Parent
:=CRLFPage
.Surface
;
572 'Git will convert LF to CRLF when checking out text files. When committing' + #
13 +
573 'text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
574 'this is the recommended setting on Windows ("core.autocrlf" is set to "true").';
582 RdbCRLF
[GC_LFOnly
]:=TRadioButton
.Create(CRLFPage
);
583 with RdbCRLF
[GC_LFOnly
] do begin
584 Parent
:=CRLFPage
.Surface
;
585 Caption
:='Checkout as-is, commit Unix-style line endings';
590 Font
.Style
:=[fsBold
];
594 LblLFOnly
:=TLabel
.Create(CRLFPage
);
595 with LblLFOnly
do begin
596 Parent
:=CRLFPage
.Surface
;
598 'Git will not perform any conversion when checking out text files. When' + #
13 +
599 'committing text files, CRLF will be converted to LF. For cross-platform projects,' + #
13 +
600 'this is the recommended setting on Unix ("core.autocrlf" is set to "input").';
608 RdbCRLF
[GC_CRLFCommitAsIs
]:=TRadioButton
.Create(CRLFPage
);
609 with RdbCRLF
[GC_CRLFCommitAsIs
] do begin
610 Parent
:=CRLFPage
.Surface
;
611 Caption
:='Checkout as-is, commit as-is';
616 Font
.Style
:=[fsBold
];
620 LblCRLFCommitAsIs
:=TLabel
.Create(CRLFPage
);
621 with LblCRLFCommitAsIs
do begin
622 Parent
:=CRLFPage
.Surface
;
624 'Git will not perform any conversions when checking out or committing' + #
13 +
625 'text files. Choosing this option is not recommended for cross-platform' + #
13 +
626 'projects ("core.autocrlf" is set to "false").';
633 // Restore the setting chosen during a previous install
.
634 Data
:=GetPreviousData('CRLF Option','CRLFAlways');
635 if Data
='LFOnly' then begin
636 RdbCRLF
[GC_LFOnly
].Checked
:=True;
637 end else if Data
='CRLFAlways' then begin
638 RdbCRLF
[GC_CRLFAlways
].Checked
:=True;
639 end else if Data
='CRLFCommitAsIs' then begin
640 RdbCRLF
[GC_CRLFCommitAsIs
].Checked
:=True;
644 * Create a custom page for finding the processes that lock a module.
647 ProcessesPage
:=CreateCustomPage(
649 'Replacing in-use files',
650 'The following applications use files that need to be replaced, please close them.'
653 ProcessesListBox
:=TListBox
.Create(ProcessesPage
);
654 with ProcessesListBox
do begin
655 Parent
:=ProcessesPage
.Surface
;
656 Width
:=ProcessesPage
.SurfaceWidth
;
657 Height
:=ProcessesPage
.SurfaceHeight
-ScaleY(8);
660 ProcessesRefresh
:=TNewButton
.Create(WizardForm
);
661 with ProcessesRefresh
do begin
663 Width
:=WizardForm
.NextButton
.Width
;
664 Height
:=WizardForm
.NextButton
.Height
;
665 Top
:=WizardForm
.NextButton
.Top
;
666 Left
:=WizardForm
.ClientWidth
-WizardForm
.NextButton
.Left
-WizardForm
.NextButton
.Width
;
668 OnClick
:=@RefreshProcessList
;
671 // This button
is only used by the uninstaller
.
674 // Initially hide the Refresh button
, show it when the process page becomes current
.
675 ProcessesRefresh
.Hide
;
678 function ShouldSkipPage(PageID
:Integer):Boolean;
680 if (ProcessesPage
<>NIL) and (PageID
=ProcessesPage
.ID
) then begin
681 // This page
is only reached
forward (by pressing
"Next", never by pressing
"Back").
682 RefreshProcessList(NIL);
683 Result
:=(GetArrayLength(Processes
)=0);
689 procedure CurPageChanged(CurPageID
:Integer);
693 // Uncheck the console font option by default
.
694 if CurPageID
=wpSelectComponents
then begin
695 for i
:=0 to WizardForm
.ComponentsList
.Items
.Count
-1 do begin
696 if WizardForm
.ComponentsList
.ItemCaption
[i
]='{#COMP_CONSOLE_FONT}' then begin
697 WizardForm
.ComponentsList
.Checked
[i
]:=False;
703 // Show the
"Refresh" button only on the processes page
.
704 if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
705 ProcessesRefresh
.Show
;
707 ProcessesRefresh
.Hide
;
711 function NextButtonClick(CurPageID
:Integer):Boolean;
717 if (PuTTYPage
<>NIL) and (CurPageID
=PuTTYPage
.ID
) then begin
718 Result
:=RdbSSH
[GS_OpenSSH
].Checked
or
719 (RdbSSH
[GS_Plink
].Checked
and FileExists(EdtPlink
.Text));
720 if not Result
then begin
721 MsgBox('Please enter a valid path to (Tortoise)Plink.exe.',mbError
,MB_OK
);
723 end else if (ProcessesPage
<>NIL) and (CurPageID
=ProcessesPage
.ID
) then begin
724 // It would have been nicer
to just disable the
"Next" button
, but the
725 // WizardForm
exports the button just
read-only
.
726 for i
:=0 to GetArrayLength(Processes
)-1 do begin
727 if not Processes
[i
].Restartable
then begin
728 MsgBox('Setup cannot continue until you close at least those applications in the list that are marked as "closing is required".',mbCriticalError
,MB_OK
);
734 Result
:=(GetArrayLength(Processes
)=0);
736 if not Result
then begin
738 'If you continue without closing the listed applications, you will need to log off and on again before changes take effect.' + #
13 + #
13 +
739 'Are you sure you want to continue anyway?',
749 // Even though the name
of this
procedure suggests otherwise most
of the
750 // code below
is only executed once after the regular installation code
751 // is finished
. This happens because
of the
if-guard right
in the
752 // beginning
of this
procedure.
753 procedure CurStepChanged(CurStep
:TSetupStep
);
755 AppDir
,DllPath
,FileName
,TempName
,Cmd
,Msg
:String;
756 BuiltIns
,ImageNames
,EnvPath
,EnvHome
,EnvSSH
:TArrayOfString
;
762 if CurStep
<>ssPostInstall
then begin
766 AppDir
:=ExpandConstant('{app}');
769 Bind the imported function addresses
773 DllPath
:=ExpandConstant('{app}\bin;{sys}');
775 // Load the list
of images from a
text file.
776 FileName
:=AppDir
+'\{#APP_BINDIMAGE}';
777 if LoadStringsFromFile(FileName
,ImageNames
) then begin
778 Count
:=GetArrayLength(ImageNames
)-1;
779 for i
:=0 to Count
do begin
780 FileName
:=AppDir
+'\'+ImageNames[i];
781 if not BindImageEx(BIND_NO_BOUND_IMPORTS or BIND_CACHE_IMPORT_DLLS,FileName,DllPath,'',0) then begin
782 Log('Line
{#__LINE__}: Error calling BindImageEx
for "'+FileName+'".');
787 Log('Line
{#__LINE__}: An exception occurred
while calling BindImageEx
.');
794 // Load the built-ins from a text file.
795 FileName:=AppDir+'\
{#APP_BUILTINS}';
796 if LoadStringsFromFile(FileName,BuiltIns) then begin
797 Count:=GetArrayLength(BuiltIns)-1;
799 // Delete those scripts from "bin" which have been replaced by built-ins in "libexec\git-core".
800 for i:=0 to Count do begin
801 FileName:=AppDir+'\bin
\'+ChangeFileExt(ExtractFileName(BuiltIns
[i
]),'');
802 if FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
803 Log('Line {#__LINE__}: Unable to delete script "'+FileName
+'", ignoring.');
807 // Create built
-ins
as aliases
for git
.exe
.
808 for i
:=0 to Count
do begin
809 FileName
:=AppDir
+'\'+BuiltIns[i];
811 // Delete any existing built-in.
812 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
813 Log('Line
{#__LINE__}: Unable
to delete existing built
-in "'+FileName+'", skipping
.');
818 // This will throw an exception on pre-WinVista systems.
819 LinkCreated:=CreateSymbolicLink(FileName,AppDir+'\bin\git
.exe
',0);
822 Log('Line
{#__LINE__}: Creating symbolic link
"'+FileName+'" failed
, will
try a hard link
.');
825 if not LinkCreated then begin
827 // This will throw an exception on pre-Win2k systems.
828 LinkCreated:=CreateHardLink(FileName,AppDir+'\bin\git
.exe
',0);
831 Log('Line
{#__LINE__}: Creating hardlink
"'+FileName+'" failed
, will
try a copy
.');
835 if not LinkCreated then begin
836 if not FileCopy(AppDir+'\bin\git
.exe
',FileName,False) then begin
837 Log('Line
{#__LINE__}: Creating copy
"'+FileName+'" failed
, giving up
.');
838 // This is not a critical error, Git could basically be used without the
839 // aliases for built-ins, so we continue.
844 // Delete any duplicate files in case we are updating from a non-libexec to a libexec directory layout.
845 if FindFirst(AppDir+'\libexec\git
-core\
*',FindRec) then begin
847 if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY)=0 then begin
848 FileName:=AppDir+'\bin
\'+FindRec
.name
;
849 if (Pos(FindRec
.name
,'git.exe')<>1) and FileExists(FileName
) and (not DeleteFile(FileName
)) then begin
850 Log('Line {#__LINE__}: Unable to delete dupe "'+FileName
+'", ignoring.');
853 until not FindNext(FindRec
);
857 Msg
:='Line {#__LINE__}: Unable to read file "{#APP_BUILTINS}".';
858 MsgBox(Msg
,mbError
,MB_OK
);
860 // This
is not a critical error
, Git could basically be used without the
861 // aliases
for built
-ins
, so we continue
.
868 if RdbCRLF
[GC_LFOnly
].checked
then begin
869 Cmd
:='core.autocrlf input';
870 end else if RdbCRLF
[GC_CRLFAlways
].checked
then begin
871 Cmd
:='core.autocrlf true';
873 Cmd
:='core.autocrlf false';
875 if not Exec(AppDir
+ '\bin\git.exe', 'config -f gitconfig ' + Cmd
,
876 AppDir
+ '\etc', SW_HIDE
, ewWaitUntilTerminated
, i
) then begin
877 Msg
:='Unable to configure the line ending conversion: ' + Cmd
;
878 MsgBox(Msg
,mbError
,MB_OK
);
880 // This
is not a critical error
, the user can probably fix it manually
,
885 Modify the environment
887 This must happen no later than ssPostInstall to make
888 "ChangesEnvironment=yes" not happend before the change!
891 FileName
:=AppDir
+'\setup.ini';
893 // Delete GIT_SSH
and SVN_SSH
if a previous installation
set them (this
is required
for the GS_OpenSSH
case).
894 EnvSSH
:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn
);
895 if (GetArrayLength(EnvSSH
)=1) and
896 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','GIT_SSH','',FileName
))=0) then begin
897 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,[]) then begin
898 Msg
:='Line {#__LINE__}: Unable to reset GIT_SSH prior to install.';
899 MsgBox(Msg
,mbError
,MB_OK
);
901 // This
is not a critical error
, the user can probably fix it manually
,
906 EnvSSH
:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn
);
907 if (GetArrayLength(EnvSSH
)=1) and
908 (CompareStr(RemoveQuotes(EnvSSH
[0]),GetIniString('Environment','SVN_SSH','',FileName
))=0) then begin
909 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn
,True,[]) then begin
910 Msg
:='Line {#__LINE__}: Unable to reset SVN_SSH prior to install.';
911 MsgBox(Msg
,mbError
,MB_OK
);
913 // This
is not a critical error
, the user can probably fix it manually
,
918 if (PuTTYPage
<>NIL) and RdbSSH
[GS_Plink
].Checked
then begin
919 SetArrayLength(EnvSSH
,1);
920 EnvSSH
[0]:=EdtPlink
.Text;
922 // Set GIT_SSH
as specified by the user
.
923 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn
,True,EnvSSH
) then begin
924 Msg
:='Line {#__LINE__}: Unable to set the GIT_SSH environment variable.';
925 MsgBox(Msg
,mbError
,MB_OK
);
927 // This
is not a critical error
, the user can probably fix it manually
,
931 // Mark that we have changed GIT_SSH by writing its value
to a
file.
932 if not SetIniString('Environment','GIT_SSH',EnvSSH
[0],FileName
) then begin
933 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
934 MsgBox(Msg
,mbError
,MB_OK
);
936 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
940 // Set SVN_SSH
as specified by the user
, but
with escaped backslashes
and quotes
.
941 StringChangeEx(EnvSSH
[0],'\','\\',True);
942 EnvSSH[0]:=AddQuotes(EnvSSH[0]);
944 if not SetEnvStrings('SVN_SSH
',IsAdminLoggedOn,True,EnvSSH) then begin
945 Msg:='Line
{#__LINE__}: Unable
to set the SVN_SSH environment variable
.';
946 MsgBox(Msg,mbError,MB_OK);
948 // This is not a critical error, the user can probably fix it manually,
952 // Mark that we have changed SVN_SSH by writing its value to a file.
953 if not SetIniString('Environment
','SVN_SSH
',EnvSSH[0],FileName) then begin
954 Msg:='Line
{#__LINE__}: Unable
to write
to file "'+FileName+'".';
955 MsgBox(Msg,mbError,MB_OK);
957 // This is not a critical error, though uninstall / reinstall will probably not run cleanly,
962 // Get the current user's directories
in PATH
.
963 EnvPath
:=GetEnvStrings('PATH',IsAdminLoggedOn
);
965 // First
, remove the installation directory from PATH
in any
case.
966 for i
:=0 to GetArrayLength(EnvPath
)-1 do begin
967 if Pos(AppDir
+'\',EnvPath[i]+'\')=1 then begin
972 // Delete HOME
if a previous installation modified it
.
973 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
974 if (GetArrayLength(EnvHome
)=1) and
975 (CompareStr(RemoveQuotes(EnvHome
[0]),GetIniString('Environment','HOME','',FileName
))=0) then begin
976 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,[]) then begin
977 Msg
:='Line {#__LINE__}: Unable to reset HOME prior to install.';
978 MsgBox(Msg
,mbError
,MB_OK
);
980 // This
is not a critical error
, the user can probably fix it manually
,
985 // Modify the PATH variable
as requested by the user
.
986 if RdbPath
[GP_Cmd
].Checked
or RdbPath
[GP_CmdTools
].Checked
then begin
987 i
:=GetArrayLength(EnvPath
);
988 SetArrayLength(EnvPath
,i
+1);
990 // List \cmd before
\bin so \cmd has higher priority
and programs
in
991 // there will be called
in favor
of those
in \bin
.
992 EnvPath
[i
]:=AppDir
+'\cmd';
994 if RdbPath
[GP_CmdTools
].Checked
then begin
995 SetArrayLength(EnvPath
,i
+2);
996 EnvPath
[i
+1]:=AppDir
+'\bin';
998 // Set HOME
for the Windows Command Prompt
, but only
if it has
not been
set manually before
.
999 EnvHome
:=GetEnvStrings('HOME',IsAdminLoggedOn
);
1000 i
:=GetArrayLength(EnvHome
);
1001 if (i
=0) or ((i
=1) and (Length(EnvHome
[0])=0)) then begin
1002 SetArrayLength(EnvHome
,1);
1003 EnvHome
[0]:=ExpandConstant('{%HOMEDRIVE}{%HOMEPATH}');
1004 if not SetEnvStrings('HOME',IsAdminLoggedOn
,True,EnvHome
) then begin
1005 Msg
:='Line {#__LINE__}: Unable to set the HOME environment variable.';
1006 MsgBox(Msg
,mbError
,MB_OK
);
1008 // This
is not a critical error
, the user can probably fix it manually
,
1012 // Mark that we have changed HOME
.
1013 if not SetIniString('Environment','HOME',EnvHome
[0],FileName
) then begin
1014 Msg
:='Line {#__LINE__}: Unable to write to file "'+FileName
+'".';
1015 MsgBox(Msg
,mbError
,MB_OK
);
1017 // This
is not a critical error
, though uninstall
/ reinstall will probably
not run cleanly
,
1024 // Set the current user
's PATH directories.
1025 if not SetEnvStrings('PATH
',IsAdminLoggedOn,True,EnvPath) then begin
1026 Msg:='Line
{#__LINE__}: Unable
to set the PATH environment variable
.';
1027 MsgBox(Msg,mbError,MB_OK);
1029 // This is not a critical error, the user can probably fix it manually,
1034 Create shortcuts that need to be created regardless of the "Don't create a Start Menu folder
" toggle
1037 Cmd:=ExpandConstant('{syswow64}\cmd.exe');
1038 TempName:='/c ""'+AppDir+'\bin\sh.exe" --login
-i
"';
1039 FileName:=AppDir+'\etc\git.ico';
1041 if IsComponentSelected('icons\quicklaunch') then begin
1043 ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\Git Bash.lnk')
1047 , '%HOMEDRIVE%%HOMEPATH%'
1053 if IsComponentSelected('icons\desktop') then begin
1055 GetShellFolder('desktop')+'\Git Bash.lnk'
1059 , '%HOMEDRIVE%%HOMEPATH%'
1066 // Create a special shortcut that does not set a working directory (Note: Since Inno Setup 5.3.11,
1067 // passing an empty WorkingDir gets replaced with {sys}, so use '.' instead).
1068 // This shortcut is used by "Git Bash
.vbs
", which in turn is run by the "Git Bash Here
" shell extension.
1070 AppDir+'\Git Bash.lnk'
1081 Create the Windows Explorer integrations
1084 if IsAdminLoggedOn then begin
1085 RootKey:=HKEY_LOCAL_MACHINE;
1087 RootKey:=HKEY_CURRENT_USER;
1090 if IsComponentSelected('ext\reg\shellhere') then begin
1091 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell','','Git Ba&sh Here')) or
1092 (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_shell\command','','wscript "'+AppDir+'\Git Bash
.vbs
" "%1"')) then begin
1093 Msg:='Line {#__LINE__}: Unable to create "Git Bash Here
" shell extension.';
1094 MsgBox(Msg,mbError,MB_OK);
1096 // This is not a critical error, the user can probably fix it manually,
1101 if IsComponentSelected('ext\reg\guihere') then begin
1102 if (not RegWriteStringValue(RootKey,'SOFTWARE\Classes\Directory\shell\git_gui','','Git &GUI Here')) or
1103 (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
1104 Msg:='Line {#__LINE__}: Unable to create "Git GUI Here
" shell extension.';
1105 MsgBox(Msg,mbError,MB_OK);
1107 // This is not a critical error, the user can probably fix it manually,
1112 // It is either the Registry-based context menu entries, or the shell extension.
1113 if IsComponentSelected('ext\cheetah') then begin
1114 DeleteContextMenuEntries;
1116 FileName:=AppDir+'\git-cheetah\git_shell_ext.dll';
1117 if not ReplaceInUseFile(FileName,FileName+'.new',True) then begin
1118 Log('Line {#__LINE__}: Replacing file "'+FileName+'" failed.');
1123 procedure RegisterPreviousData(PreviousDataKey:Integer);
1127 // Git Path options.
1129 if RdbPath[GP_BashOnly].Checked then begin
1131 end else if RdbPath[GP_Cmd].Checked then begin
1133 end else if RdbPath[GP_CmdTools].Checked then begin
1136 SetPreviousData(PreviousDataKey,'Path Option',Data);
1140 if (PuTTYPage=NIL) or RdbSSH[GS_OpenSSH].Checked then begin
1142 end else if RdbSSH[GS_Plink].Checked then begin
1145 SetPreviousData(PreviousDataKey,'SSH Option',Data);
1147 // Line ending conversion options.
1149 if RdbCRLF[GC_LFOnly].Checked then begin
1151 end else if RdbCRLF[GC_CRLFAlways].Checked then begin
1153 end else if RdbCRLF[GC_CRLFCommitAsIs].Checked then begin
1154 Data:='CRLFCommitAsIs';
1156 SetPreviousData(PreviousDataKey,'CRLF Option',Data);
1163 function InitializeUninstall:Boolean;
1167 ExitButton,RefreshButton:TButton;
1171 Form:=CreateCustomForm;
1173 Form.Caption:='Git Uninstall: Removing in-use files';
1174 Form.ClientWidth:=ScaleX(500);
1175 Form.ClientHeight:=ScaleY(256);
1178 Info:=TLabel.Create(Form);
1184 Caption:='The following applications use files that need to be removed, please close them.';
1187 ContinueButton:=TButton.Create(Form);
1188 with ContinueButton do begin
1190 Left:=Form.ClientWidth-ScaleX(75+10);
1191 Top:=Form.ClientHeight-ScaleY(23+10);
1194 Caption:='Continue';
1198 ExitButton:=TButton.Create(Form);
1199 with ExitButton do begin
1201 Left:=ContinueButton.Left-ScaleX(75+6);
1202 Top:=ContinueButton.Top;
1206 ModalResult:=mrCancel;
1210 RefreshButton:=TButton.Create(Form);
1211 with RefreshButton do begin
1214 Top:=ExitButton.Top;
1218 OnClick:=@RefreshProcessList;
1221 ProcessesListBox:=TListBox.Create(Form);
1222 with ProcessesListBox do begin
1225 Top:=Info.Top+Info.Height+11;
1226 Width:=Form.ClientWidth-ScaleX(11*2);
1227 Height:=ContinueButton.Top-ScaleY(11*4);
1230 Form.ActiveControl:=ContinueButton;
1232 RefreshProcessList(NIL);
1233 if GetArrayLength(Processes)>0 then begin
1234 // Now that these dialogs are going to be shown, we should probably
1235 // disable the "Are you sure
to remove Git?
" confirmation dialog, but
1236 // unfortunately that is not possible with Inno Setup currently.
1237 Result:=(Form.ShowModal()=mrOk);
1239 // Note: The number of processes might have changed during a refresh.
1240 if Result and (GetArrayLength(Processes)>0) then begin
1242 'If you continue without closing the listed applications, you will need to log off and on again to remove some files manually.' + #13 + #13 +
1243 'Are you sure you want to continue anyway?',
1256 // Even though the name of this function suggests otherwise most of the
1257 // code below is only executed right before the actual uninstallation.
1258 // This happens because of the if-guard right in the beginning of this
1260 procedure CurUninstallStepChanged(CurUninstallStep:TUninstallStep);
1262 AppDir,FileName,Msg:String;
1263 EnvPath,EnvHome,EnvSSH:TArrayOfString;
1266 if CurUninstallStep<>usUninstall then begin
1270 // Reset the console font (the FontType is reset in the Registry section).
1271 if IsComponentInstalled('consolefont') then begin
1272 if MsgBox('Do you want to revert the TrueType font setting for all console windows?',mbConfirmation,MB_YESNO)=IDYES then begin
1273 RegWriteDWordValue(HKEY_CURRENT_USER,'Console','FontFamily',0);
1274 RegWriteDWordValue(HKEY_CURRENT_USER,'Console','FontSize',0);
1275 RegWriteDWordValue(HKEY_CURRENT_USER,'Console','FontWeight',0);
1280 Modify the environment
1282 This must happen no later than usUninstall to make
1283 "ChangesEnvironment
=yes
" not happend before the change!
1286 AppDir:=ExpandConstant('{app}');
1287 FileName:=AppDir+'\setup.ini';
1289 // Delete the current user's GIT_SSH and SVN_SSH if we set it.
1290 EnvSSH:=GetEnvStrings('GIT_SSH',IsAdminLoggedOn);
1291 if (GetArrayLength(EnvSSH)=1) and
1292 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment','GIT_SSH','',FileName))=0) then begin
1293 if not SetEnvStrings('GIT_SSH',IsAdminLoggedOn,True,[]) then begin
1294 Msg:='Line {#__LINE__}: Unable to revert any possible changes to GIT_SSH.';
1295 MsgBox(Msg,mbError,MB_OK);
1297 // This is not a critical error, the user can probably fix it manually,
1302 EnvSSH:=GetEnvStrings('SVN_SSH',IsAdminLoggedOn);
1303 if (GetArrayLength(EnvSSH)=1) and
1304 (CompareStr(RemoveQuotes(EnvSSH[0]),GetIniString('Environment','SVN_SSH','',FileName))=0) then begin
1305 if not SetEnvStrings('SVN_SSH',IsAdminLoggedOn,True,[]) then begin
1306 Msg:='Line {#__LINE__}: Unable to revert any possible changes to SVN_SSH.';
1307 MsgBox(Msg,mbError,MB_OK);
1309 // This is not a critical error, the user can probably fix it manually,
1314 // Get the current user's directories in PATH.
1315 EnvPath:=GetEnvStrings('PATH',IsAdminLoggedOn);
1317 // Remove the installation directory from PATH in any case, even if it
1318 // was not added by the installer.
1319 for i:=0 to GetArrayLength(EnvPath)-1 do begin
1320 if Pos(AppDir+'\',EnvPath[i]+'\')=1 then begin
1325 // Reset the current user's directories in PATH.
1326 if not SetEnvStrings('PATH',IsAdminLoggedOn,True,EnvPath) then begin
1327 Msg:='Line {#__LINE__}: Unable to revert any possible changes to PATH.';
1328 MsgBox(Msg,mbError,MB_OK);
1330 // This is not a critical error, the user can probably fix it manually,
1334 // Reset the current user's HOME if we modified it.
1335 EnvHome:=GetEnvStrings('HOME',IsAdminLoggedOn);
1336 if (GetArrayLength(EnvHome)=1) and
1337 (CompareStr(RemoveQuotes(EnvHome[0]),GetIniString('Environment','HOME','',FileName))=0) then begin
1338 if not SetEnvStrings('HOME',IsAdminLoggedOn,True,[]) then begin
1339 Msg:='Line {#__LINE__}: Unable to revert any possible changes to HOME.';
1340 MsgBox(Msg,mbError,MB_OK);
1342 // This is not a critical error, the user can probably fix it manually,
1347 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
1348 Msg:='Line {#__LINE__}: Unable to delete file "'+FileName+'".';
1349 MsgBox(Msg,mbError,MB_OK);
1351 // This is not a critical error, the user can probably fix it manually,
1356 Delete the Windows Explorer integrations
1359 DeleteContextMenuEntries;
1361 FileName:=AppDir+'\git-cheetah\git_shell_ext.dll';
1362 if FileExists(FileName) then begin
1363 if not UnregisterServer(Is64BitInstallMode,FileName,False) then begin
1364 Msg:='Line {#__LINE__}: Unable to unregister file "'+FileName+'". Please do it manually by running "regsvr32
/u
'+ExtractFileName(FileName)+'".';
1365 MsgBox(Msg,mbError,MB_OK);
1369 if not DeleteFile(FileName) then begin
1370 Msg:='Line {#__LINE__}: Unable to delete file "'+FileName+'". Please do it manually after logging off and on again.';
1371 MsgBox(Msg,mbError,MB_OK);