1 #define APP_NAME
'git-cola'
2 #define APP_LONGNAME
'git-cola - The highly caffeinated git GUI'
3 #define APP_VERSION
'%APPVERSION%'
4 #define APP_URL
'http://git-cola.github.com/'
8 InternalCompressLevel
=max
9 OutputBaseFilename
={#emit APP_NAME+'-'+APP_VERSION}
15 AppName
={#emit APP_LONGNAME}
16 AppPublisherURL
={#emit APP_URL}
17 AppVersion
={#emit APP_VERSION}
18 AppVerName
={#emit APP_LONGNAME+' '+APP_VERSION}
19 ChangesEnvironment
=yes
20 DefaultDirName
={pf}\
{#emit APP_NAME}
21 DefaultGroupName
={#emit APP_LONGNAME}
23 InfoBeforeFile
=etc\gpl
-2.0.rtf
24 PrivilegesRequired
=none
25 UninstallDisplayIcon
=etc\git
.ico
28 SetupIconFile
=etc\git
.ico
29 WizardSmallImageFile
=etc\git
.bmp
32 Name
: quicklaunchicon; Description
: "Create a &Quick Launch icon"; GroupDescription
: "Additional icons:"; Flags
: checkedonce
33 Name
: desktopicon; Description
: "Create a &Desktop icon"; GroupDescription
: "Additional icons:"; Flags
: checkedonce
34 Name
: guiextension
; Description
: "Add ""Git &Cola Here"""; GroupDescription
: "Windows Explorer integration:"; Flags
: checkedonce
37 Source
: "*"; DestDir
: "{app}"; Excludes
: "\*.bmp, \install.*, \tmp.*, \bin\*install*"; Flags
: recursesubdirs
38 Source
: "etc\ReleaseNotes.txt"; DestDir
: "{app}\etc"; Flags
: isreadme
41 Name
: "{group}\git-cola"; Filename
: "{code:GetPythonExe}"; Parameters
: """{app}\bin\git-cola.pyw"" --prompt --git-path ""{code:GetGitExe}"""; WorkingDir
: "%USERPROFILE%"; IconFilename
: "{app}\etc\git.ico"
42 Name
: "{group}\git-dag"; Filename
: "{code:GetPythonExe}"; Parameters
: """{app}\bin\git-dag.pyw"" --prompt --git-path ""{code:GetGitExe}"""; WorkingDir
: "%USERPROFILE%"; IconFilename
: "{app}\etc\git.ico"
43 Name
: "{group}\git-cola Homepage"; Filename
: "{#emit APP_URL}"; WorkingDir
: "%USERPROFILE%";
44 Name
: "{group}\Release Notes"; Filename
: "{app}\etc\ReleaseNotes.txt"; WorkingDir
: "%USERPROFILE%";
45 Name
: "{group}\License"; Filename
: "{app}\etc\gpl-2.0.rtf"; WorkingDir
: "%USERPROFILE%";
46 Name
: "{group}\Uninstall git-cola"; Filename
: "{uninstallexe}"
47 Name
: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\git-cola"; Filename
: "{code:GetPythonExe}"; Parameters
: """{app}\bin\git-cola.pyw"" --prompt --git-path ""{code:GetGitExe}"""; WorkingDir
: "%USERPROFILE%"; IconFilename
: "{app}\etc\git.ico"; Tasks
: quicklaunchicon
48 Name
: "{code:GetShellFolder|desktop}\git-cola"; Filename
: "{code:GetPythonExe}"; Parameters
: """{app}\bin\git-cola.pyw"" --prompt --git-path ""{code:GetGitExe}"""; WorkingDir
: "%USERPROFILE%"; IconFilename
: "{app}\etc\git.ico"; Tasks
: desktopicon
49 Name
: "{code:GetShellFolder|desktop}\git-dag"; Filename
: "{code:GetPythonExe}"; Parameters
: """{app}\bin\git-dag.pyw"" --prompt --git-path ""{code:GetGitExe}"""; WorkingDir
: "%USERPROFILE%"; IconFilename
: "{app}\etc\git.ico"; Tasks
: desktopicon
52 BeveledLabel
={#emit APP_URL}
53 SetupAppTitle
={#emit APP_NAME} Setup
54 SetupWindowTitle
={#emit APP_NAME} Setup
57 Type: files; Name
: "{app}\bin\*"
58 Type: files; Name
: "{app}\etc\*"
59 Type: files; Name
: "{app}\share\git-cola\bin\*"
60 Type: files; Name
: "{app}\share\git-cola\icons\*"
61 Type: files; Name
: "{app}\share\git-cola\lib\cola\*"
62 Type: files; Name
: "{app}\share\git-cola\lib\cola\classic\*"
63 Type: files; Name
: "{app}\share\git-cola\lib\cola\dag\*"
64 Type: files; Name
: "{app}\share\git-cola\lib\cola\main\*"
65 Type: files; Name
: "{app}\share\git-cola\lib\cola\merge\*"
66 Type: files; Name
: "{app}\share\git-cola\lib\cola\models\*"
67 Type: files; Name
: "{app}\share\git-cola\lib\cola\prefs\*"
68 Type: files; Name
: "{app}\share\git-cola\lib\cola\stash\*"
69 Type: files; Name
: "{app}\share\git-cola\lib\cola\widgets\*"
70 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\classic"
71 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\dag"
72 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\main"
73 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\merge"
74 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\models"
75 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\prefs"
76 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\stash"
77 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola\widgets"
78 Type: dirifempty; Name
: "{app}\share\git-cola\lib\cola"
79 Type: dirifempty; Name
: "{app}\share\git-cola\lib"
80 Type: dirifempty; Name
: "{app}\share\git-cola\icons"
81 Type: dirifempty; Name
: "{app}\share\git-cola\bin"
82 Type: dirifempty; Name
: "{app}\etc"
83 Type: dirifempty; Name
: "{app}\bin"
91 PythonPage
:TWizardPage
;
96 function GetEnvStrings(VarName
:string;AllUsers
:Boolean):TArrayOfString
;
104 // See http
://www
.jrsoftware
.org
/isfaq
.php#env
105 if AllUsers
then begin
106 // We ignore errors here
. The resulting
array of strings will be empty
.
107 RegQueryStringValue(HKEY_LOCAL_MACHINE
,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',VarName
,Path
);
109 // We ignore errors here
. The resulting
array of strings will be empty
.
110 RegQueryStringValue(HKEY_CURRENT_USER
,'Environment',VarName
,Path
);
113 // Make sure we have at least one semicolon
.
116 // Split the directories
in PATH into an
array of strings
.
118 SetArrayLength(Result
,0);
122 SetArrayLength(Result
,i
+1);
124 Result
[i
]:=Copy(Path
,1,p
-1);
127 Path
:=Copy(Path
,p
+1,Length(Path
));
132 function SetEnvStrings(VarName
:string;AllUsers
,DeleteIfEmpty
:Boolean;DirStrings
:TArrayOfString
):Boolean;
137 // Merge all non
-empty directory strings into a PATH variable
.
139 for i
:=0 to GetArrayLength(DirStrings
)-1 do begin
140 if Length(DirStrings
[i
])>0 then begin
141 if Length(Path
)>0 then begin
142 Path
:=Path
+';'+DirStrings
[i
];
149 // See http
://www
.jrsoftware
.org
/isfaq
.php#env
150 if AllUsers
then begin
151 KeyName
:='SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
152 if DeleteIfEmpty
and (Length(Path
)=0) then begin
153 Result
:=(not RegValueExists(HKEY_LOCAL_MACHINE
,KeyName
,VarName
))
154 or RegDeleteValue(HKEY_LOCAL_MACHINE
,KeyName
,VarName
);
156 Result
:=RegWriteStringValue(HKEY_LOCAL_MACHINE
,KeyName
,VarName
,Path
);
159 KeyName
:='Environment';
160 if DeleteIfEmpty
and (Length(Path
)=0) then begin
161 Result
:=(not RegValueExists(HKEY_CURRENT_USER
,KeyName
,VarName
))
162 or RegDeleteValue(HKEY_CURRENT_USER
,KeyName
,VarName
);
164 Result
:=RegWriteStringValue(HKEY_CURRENT_USER
,KeyName
,VarName
,Path
);
170 procedure BrowseForPythonFolder(Sender
:TObject
);
174 Path
:=GetPreviousData('PythonPath', 'C:\Python26');
175 EdtPython
.Text:=Path
;
176 Path
:=ExtractFilePath(EdtPython
.Text);
177 BrowseForFolder('Please select the Python folder:',Path
,False);
178 Path
:=Path
+'\pythonw.exe';
179 if FileExists(Path
) then begin
180 EdtPython
.Text:=Path
;
182 MsgBox('Please enter a valid path to pythonw.exe.',mbError
,MB_OK
);
186 function GetPythonExe(Param
: String): String;
188 Result
:=EdtPython
.Text;
191 procedure BrowseForGitFolder(Sender
:TObject
);
196 Path
:=GetPreviousData('GitPath', 'C:\Program Files\Git');
198 Path
:=ExtractFilePath(EdtGit
.Text);
199 BrowseForFolder('Please select the Git folder:',Path
,False);
203 Check for both $DIR\git.exe and $DIR\bin\git.exe
206 Path
:=OldPath
+'\bin\git.exe';
207 if FileExists(Path
) then begin
212 Path
:=OldPath
+'\git.exe';
213 if FileExists(Path
) then begin
216 MsgBox('Please enter a valid path to git.exe.',mbError
,MB_OK
);
221 function GetGitExe(Param
: String): String;
226 procedure RegisterPreviousData(PreviousDataKey
:Integer);
230 Path
:=ExtractFilePath(EdtPython
.Text);
231 SetPreviousData(PreviousDataKey
, 'PythonPath', Path
);
233 Path
:=ExtractFilePath(ExtractFilePath(EdtGit
.Text));
234 SetPreviousData(PreviousDataKey
, 'GitPath', Path
);
242 procedure InitializeWizard
;
249 // Create a custom page
for finding Python
250 PythonPage
:=CreateCustomPage(
253 'Where is your Python folder?'
256 LblPython
:=TLabel
.Create(PythonPage
);
257 with LblPython
do begin
258 Parent
:=PythonPage
.Surface
;
259 Caption
:= 'Please provide the path to pythonw.exe.';
266 EdtPython
:=TEdit
.Create(PythonPage
);
267 with EdtPython
do begin
268 Parent
:=PythonPage
.Surface
;
269 Text:=GetPreviousData('PythonPath', 'C:\Python26');
270 Text:=Text+'pythonw.exe';
271 if not FileExists(Text) then begin
280 BtnPython
:=TButton
.Create(PythonPage
);
281 with BtnPython
do begin
282 Parent
:=PythonPage
.Surface
;
284 OnClick
:=@BrowseForPythonFolder
;
291 // Create a custom page
for finding Git
292 GitPage
:=CreateCustomPage(
295 'Where is your Git folder?'
298 LblGit
:=TLabel
.Create(GitPage
);
300 Parent
:=GitPage
.Surface
;
301 Caption
:= 'Please provide the path to git.exe.';
308 EdtGit
:=TEdit
.Create(GitPage
);
310 Parent
:=GitPage
.Surface
;
311 Text:=GetPreviousData('GitPath', 'C:\Program Files\Git');
312 Text:=Text+'git.exe';
313 if not FileExists(Text) then begin
322 BtnGit
:=TButton
.Create(GitPage
);
324 Parent
:=GitPage
.Surface
;
326 OnClick
:=@BrowseForGitFolder
;
334 function NextButtonClick(CurPageID
:Integer):Boolean;
336 if CurPageID
= PythonPage
.ID
then begin
337 Result
:=FileExists(EdtPython
.Text);
339 if not Result
then begin
340 MsgBox('Please enter a valid path to pythonw.exe.',mbError
,MB_OK
);
345 if CurPageID
= GitPage
.ID
then begin
346 Result
:=FileExists(EdtGit
.Text);
348 if not Result
then begin
349 MsgBox('Please enter a valid path to git.exe.',mbError
,MB_OK
);
357 procedure CurStepChanged(CurStep
:TSetupStep
);
359 AppDir
,BinDir
,Msg
:string;
360 EnvPath
:TArrayOfString
;
364 if CurStep
<>ssPostInstall
then begin
368 AppDir
:=ExpandConstant('{app}');
369 BinDir
:=ExpandConstant('{app}\bin');
372 Modify the environment
374 This must happen no later than ssPostInstall to make
375 "ChangesEnvironment=yes" not happend before the change!
378 // Get the current user
's directories in PATH.
379 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
381 // First, remove the installation directory from PATH in any case.
382 for i:=0 to GetArrayLength(EnvPath)-1 do begin
383 if Pos(AppDir,EnvPath[i])=1 then begin
388 // Modify the PATH variable as requested by the user.
389 i:=GetArrayLength(EnvPath);
390 SetArrayLength(EnvPath,i+1);
392 // Add \bin to the path
395 // Set the current user's PATH directories
.
396 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
397 Msg
:='Line {#emit __LINE__}: Unable to set the PATH environment variable.';
398 MsgBox(Msg
,mbError
,MB_OK
);
400 // This
is not a critical error
, the user can probably fix it manually
,
405 Create the Windows Explorer shell extensions
408 if IsAdminLoggedOn
then begin
409 RootKey
:=HKEY_LOCAL_MACHINE
;
411 RootKey
:=HKEY_CURRENT_USER
;
414 if IsTaskSelected('guiextension') then begin
415 if (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_cola','','Git &Cola Here'))
416 or (not RegWriteStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_cola\command','','"'+EdtPython
.Text+'" "'+AppDir
+'\bin\git-cola.pyw" "--repo" "%1" "--git-path" "'+EdtGit
.Text+'"')) then begin
417 Msg
:='Line {#emit __LINE__}: Unable to create "Git Cola Here" shell extension.';
418 MsgBox(Msg
,mbError
,MB_OK
);
420 // This
is not a critical error
, the user can probably fix it manually
,
430 function InitializeUninstall
:Boolean;
435 procedure CurUninstallStepChanged(CurUninstallStep
:TUninstallStep
);
437 AppDir
,Command
,Msg
:string;
438 EnvPath
:TArrayOfString
;
442 if CurUninstallStep
<>usUninstall
then begin
447 Modify the environment
449 This must happen no later than usUninstall to make
450 "ChangesEnvironment=yes" not happend before the change!
453 AppDir
:=ExpandConstant('{app}');
454 Command
:=AppDir
+'\setup.ini';
456 // Get the current user
's directories in PATH.
457 EnvPath:=GetEnvStrings('PATH
',IsAdminLoggedOn);
459 // Remove the installation directory from PATH in any case, even if it
460 // was not added by the installer.
461 for i:=0 to GetArrayLength(EnvPath)-1 do begin
462 if Pos(AppDir,EnvPath[i])=1 then begin
467 // Reset the current user's directories
in PATH
.
468 if not SetEnvStrings('PATH',IsAdminLoggedOn
,True,EnvPath
) then begin
469 Msg
:='Line {#emit __LINE__}: Unable to revert any possible changes to PATH.';
470 MsgBox(Msg
,mbError
,MB_OK
);
472 // This
is not a critical error
, the user can probably fix it manually
,
476 if (FileExists(Command
) and (not DeleteFile(Command
))) then begin
477 Msg
:='Line {#emit __LINE__}: Unable to delete file "'+Command
+'".';
478 MsgBox(Msg
,mbError
,MB_OK
);
480 // This
is not a critical error
, the user can probably fix it manually
,
485 Delete the Windows Explorer shell extensions
488 if IsAdminLoggedOn
then begin
489 RootKey
:=HKEY_LOCAL_MACHINE
;
491 RootKey
:=HKEY_CURRENT_USER
;
495 RegQueryStringValue(RootKey
,'SOFTWARE\Classes\Directory\shell\git_cola\command','',Command
);
496 if Pos(AppDir
,Command
)>0 then begin
497 if not RegDeleteKeyIncludingSubkeys(RootKey
,'SOFTWARE\Classes\Directory\shell\git_cola') then begin
498 Msg
:='Line {#emit __LINE__}: Unable to remove "Git Cola Here" shell extension.';
499 MsgBox(Msg
,mbError
,MB_OK
);
501 // This
is not a critical error
, the user can probably fix it manually
,
507 function GetShellFolder(Param
:string):string;
509 if IsAdminLoggedOn
then begin
510 Param
:='{common'+Param
+'}';
512 Param
:='{user'+Param
+'}';
514 Result
:=ExpandConstant(Param
);