Win-Installer: refactor, move some parts of the script into include files

git-svn-id: trunk@42526 -
This commit is contained in:
martin 2013-08-30 12:00:20 +00:00
parent 46fe5c5c38
commit 4e1b98a5f2
7 changed files with 688 additions and 612 deletions

5
.gitattributes vendored
View File

@ -7912,6 +7912,11 @@ tools/install/win/build-fpc.bat svneol=native#text/x-msdos-program
tools/install/win/build-lazarus.bat svneol=native#text/x-msdos-program
tools/install/win/create_installer.bat svneol=native#text/x-msdos-program
tools/install/win/environmentoptions.xml svneol=native#text/xml
tools/install/win/innoscript/about.pas svneol=native#text/pascal
tools/install/win/innoscript/common.pas svneol=native#text/pascal
tools/install/win/innoscript/conffile.pas svneol=native#text/pascal
tools/install/win/innoscript/secondary.pas svneol=native#text/pascal
tools/install/win/innoscript/uninst.pas svneol=native#text/pascal
tools/install/win/lazarus-cross.iss svneol=native#text/plain
tools/install/win/lazarus.de.isl svneol=native#text/plain
tools/install/win/lazarus.def.isl svneol=native#text/plain

View File

@ -0,0 +1,21 @@
// Info displayed during install progress
Procedure AddInfoComponentsToProgressWizzard;
var
m: TMemo;
begin
WizardForm.ProgressGauge.Parent.Handle;
m:= TMemo.Create(WizardForm);
m.Parent:=WizardForm.ProgressGauge.Parent;
m.Top := WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + 10;
m.Left := WizardForm.ProgressGauge.Left;
m.Width := WizardForm.ProgressGauge.Width ;
m.Height := WizardForm.ProgressGauge.Parent.Height - WizardForm.ProgressGauge.Height - WizardForm.ProgressGauge.Top - 15;
m.ReadOnly := True;
m.WordWrap := True;
m.ScrollBars := ssVertical;
m.Text := Format(CustomMessage('DuringInstall'), [#13#10]);
end;

View File

@ -0,0 +1,109 @@
function dbgsBool(b: Boolean): String; begin Result := 'False'; if b then Result := 'True'; end;
function GetAppId(param:string): String;
var
s: String;
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) or IsSecondaryUpdate then
begin
// Secondary
s := RemoveBackslashUnlessRoot(Lowercase(WizardDirValue));
Result := 'lazarus_sec_'+GetSHA1OfString(s) + '_' + IntToStr(length(s));
end
else
Result := 'lazarus';
if ForcePrimaryAppId then
Result := 'lazarus';
Log('App-Id='+Result);
end;
function GetPCPForDelete(param:string): String;
// Used by [InstallDelete]
// Name: {code:GetPCPForDelete}*.xml; Type: files; Tasks: delusersettings
// ... delete primary conf
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) then
begin
if SecondPCP = '' then
Result := AddBackslash(WizardDirValue) // some fallback
else
Result := AddBackslash(SecondPCP);
end
else
Result := ExpandConstant('{localappdata}\lazarus\');
Log('PrimConf for Delete='+Result);
end;
function IsDirEmpty(s: String): Boolean;
var
FindRec: TFindRec;
begin
Result := not DirExists(s);
if Result then exit;
SetCurrentDir(s);
Result := not FindFirst('*', FindRec);
if Result then exit;
if (FindRec.Name = '.') or (FindRec.Name = '..') then Result := not FindNext(FindRec);
if (not Result) and ((FindRec.Name = '.') or (FindRec.Name = '..')) then Result := not FindNext(FindRec);
FindClose(FindRec);
end;
function SaveCustomMessage(AMsgId, ADefaulText: String): String;
begin
try
Result := CustomMessage(AMsgId);
except
Result := ADefaulText;
end;
end;
function GetDefDir( def: String ) : String;
// Used by [SETUP]
// DefaultDirName={code:GetDefDir|{sd}\lazarus}
begin
if Pos( ' ', def ) > 0 then
begin
def := Copy( def, 1, Pos( ' ', def ) - 1 ) + '\NoFolderSpace';
end;
Result := def;
end;
procedure UpdateEnvironmentOptions();
// used by [FILES]
// Source: environmentoptions.xml; DestDir: {app}; AfterInstall: UpdateEnvironmentOptions; DestName: environmentoptions.xml
var
FileName, Content: string;
s: Ansistring;
begin
FileName := ExpandConstant(CurrentFileName);
LoadStringFromFile(FileName, s);
Content := s;
StringChange(Content, '%Temp%', GetTempDir);
StringChange(Content, '%LazDir%', ExpandConstant('{app}'));
StringChange(Content, '%FpcBinDir%', ExpandConstant('{app}\fpc\{#FPCVersion}\bin\{#FPCFullTarget}\'));
SaveStringToFile(FileName, Content, False);
end;
function IsHKLMWriteable(): boolean;
begin
Result := IsAdminLoggedOn or IsPowerUserLoggedOn;
end;
function IsHKLMNotWriteable: boolean;
begin
Result := not IsHKLMWriteable();
end;
function GetAssociateDesc(const ext: string): string;
var
AmpersandPos: integer;
begin
Result := FmtMessage(CustomMessage('AssocFileExtension'), ['Lazarus',ext]);
AmpersandPos := pos('&', Result);
if AmpersandPos>0 then
Delete(Result, AmpersandPos, 1);
end;

View File

@ -0,0 +1,83 @@
type
TCfgFileState = (csNoFile, csUnreadable, csParsedOk);
var
NewCFGFile: TStringList;
function LoadCFGFile(AFolder: String; var AList: TStringList): Boolean;
var
cfgfile: String;
begin
if AList = nil then
AList := TStringList.Create
else
AList.Clear;
cfgfile := AddBackslash(AFolder) + 'lazarus.cfg';
Result := FileExists(cfgfile);
if not Result then
exit;
AList.LoadFromFile(cfgfile);
end;
procedure CreateCFGFile(APCP: String; var AList: TStringList);
var
cfgfile: String;
begin
if AList = nil then
AList := TStringList.Create
else
AList.Clear;
AList.add('--primary-config-path=' + APCP);
end;
function ParseCFGFile(AFolder: String; var APrimConfDir: String): TCfgFileState;
var
s, cfgfile: String;
i: Integer;
l: TStringList;
begin
cfgfile := AddBackslash(AFolder) + 'lazarus.cfg';
Result := csNoFile;
if not FileExists(cfgfile) then begin
Log('ParseCFGFile not existent');
exit;
end;
Result := csUnreadable;
l := TStringList.Create;
l.LoadFromFile(cfgfile);
for i := 0 to l.Count - 1 do
if copy(l[i], 1, 6) = '--pcp=' then
s := copy(l[i], 7, length(l[i]))
else
if copy(l[i], 1, 22) = '--primary-config-path=' then
s := copy(l[i], 23, length(l[i]));
l.Free;
if s = '' then
exit;
if (s[1] = '"') and (s[length(s)] = '"') then
s := copy(s, 2, length(s)-2)
else
if (s[1] = '''') and (s[length(s)] = '''') then
s := copy(s, 2, length(s)-2)
if s = '' then
exit;
if (not FileExists(AddBackslash(s) + 'environmentoptions.xml')) and
(not IsDirEmpty(s))
then begin
Log('ParseCFGFile unreadable');
exit;
end;
Result := csParsedOk;
APrimConfDir := s;
Log('ParseCFGFile OK');
end;

View File

@ -0,0 +1,83 @@
var
wpAskConfDir: TInputDirWizardPage;
Procedure AddSecondaryCheckBoxToTargetDirWizzard;
begin
if (CheckSecondInstall <> nil) then
exit;
WizardForm.DirEdit.Parent.Handle;
CheckSecondInstall := TCheckBox.Create(WizardForm);
CheckSecondInstall.Parent:=WizardForm.DirEdit.Parent;
CheckSecondInstall.Top := WizardForm.DirEdit.Top + WizardForm.DirEdit.Height + 10;
CheckSecondInstall.Left := WizardForm.DirEdit.Left;
CheckSecondInstall.Width := WizardForm.DirEdit.Parent.Width - WizardForm.DirEdit.Left;
CheckSecondInstall.Caption := CustomMessage('CheckSecondClick');
CheckSecondLabel := TLabel.Create(WizardForm);
CheckSecondLabel.Parent:=WizardForm.DirEdit.Parent;
CheckSecondLabel.AutoSize := False;
CheckSecondLabel.WordWrap := True;
CheckSecondLabel.Top := CheckSecondInstall.Top + CheckSecondInstall.Height + 10;
CheckSecondLabel.Left := WizardForm.DirEdit.Left;
CheckSecondLabel.Width := WizardForm.DirEdit.Parent.Width - WizardForm.DirEdit.Left;
CheckSecondLabel.Height := WizardForm.DirEdit.Parent.Height - CheckSecondLabel.Top - 15;
CheckSecondLabel.Caption := CustomMessage('CheckSecondInfo');
end;
procedure CreateSecondaryConfFolderAndNameWizardPage;
begin
wpAskConfDir := CreateInputDirPage(
wpSelectDir,
CustomMessage('SecondConfCapt'),
CustomMessage('SecondConfCapt2'),
CustomMessage('SecondConfBody'),
False,
'laz_conf'
);
wpAskConfDir.Add('Folder for config');
end;
Procedure CreateOrSaveConfigFile;
begin
if (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) then begin
if (NewCFGFile <> nil) then
try
NewCFGFile.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
ForceDirectories(SecondPCP);
except
MsgBox('Internal Error (1): Could not save CFG for secondary install', mbConfirmation, MB_OK);
end
else begin
MsgBox('Internal Error (2): Could not save CFG for secondary install', mbConfirmation, MB_OK);
end;
end
else
if (UninstallDoneState <> uiUnknown) and (IsSecondaryUpdate) and
(not FileExists(AddBackslash(WizardDirValue) + 'lazarus.cfg'))
then begin
// cfg was uninstalled / restore
if (NewCFGFile <> nil) then
try
NewCFGFile.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
except
MsgBox('Internal Error (3): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end
else
if (UninstDir = WizardDirValue) and (CFGFileForUninstDir <> nil) and
(CFGFileForUninstDir.count > 0)
then begin
try
CFGFileForUninstDir.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
except
MsgBox('Internal Error (4): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end
end
else begin
MsgBox('Internal Error (5): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end;
end;
end;

View File

@ -0,0 +1,368 @@
type
TUninstallState = (
uiUnknown,
UIDone, // There IS no uninstaller, OR it was already executed during this install
UIOtherNeeded, // The uninstaller ('Inno Setup: App Path') points to a different Path than "WizardFolder"
// Uninstall for OTHER folder NEEDED
uiDestNeeded, // Uninstaller for "WizardFolder" found
// Uninstall for DESTINATION folder NEEDED
uiInconsistent // Path of uninstaller and lazarus to be removed, do not match
);
var
UninstallState: TUninstallState;
UninstallDoneState: TUninstallState; // Set only if uninstall was executed
UnInstallerInAppPath: Boolean; // The uninstaller is in the directory that it will remove
OldPath, // Registry 'Inno Setup: App Path'
OldName, // Registry 'DisplayName'
UnInstaller: String; // Registry 'UninstallString'
PathEqual: Boolean;
UninstDir: String;
CFGFileForUninstDir: TStringList;
var
wpAskUnistall: TWizardPage;
wpLabel1, wpLabel2, wpLabel3, wpLabel4: TNewStaticText;
wpCheckBox: TNewCheckBox;
wpButton: TNewButton;
function dbgsUiState(u: TUninstallState): String;
begin
case u of
uiUnknown: Result := 'uiUnknown';
UIDone: Result := 'UIDone';
UIOtherNeeded: Result := 'UIOtherNeeded';
uiDestNeeded: Result := 'uiDestNeeded';
uiInconsistent: Result := 'uiInconsistent';
end;
end;
function GetUninstallData(ARegName: String): String; // Get one entry from registry e.g. 'UninstallString'
var
Path: String;
begin
Path := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+GetAppId('')+'_is1');
Result := '';
if not RegQueryStringValue(HKLM, Path, ARegName, Result) then
RegQueryStringValue(HKCU, Path, ARegName, Result);
end;
procedure InitializeUninstallInfo;
begin
UninstallState := uiUnknown;
UninstallDoneState := uiUnknown;
end;
procedure UpdateUninstallInfo;
begin
Log('Enter UninstallState '+dbgsUiState(UninstallState));
OldPath := '';
OldName := '';
UnInstaller := '';
PathEqual := False;
if UninstallState = uiDone then exit;
UnInstaller := RemoveQuotes(GetUninstallData('UninstallString'));
if (UnInstaller <> '') and FileExists(UnInstaller) then
begin
OldPath := RemoveQuotes((GetUninstallData('Inno Setup: App Path')));
OldName := GetUninstallData('DisplayName');
PathEqual := (OldPath <> '') and
(CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(WizardDirValue)) = 0);
if PathEqual then
UninstallState := uiDestNeeded
else
UninstallState := uiOtherNeeded;
UnInstallerInAppPath := (CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(ExtractFilePath(UnInstaller))) = 0);
if (not UnInstallerInAppPath) and
( (CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(WizardDirValue)) = 0) or
(CompareText(RemoveBackslashUnlessRoot(ExtractFilePath(UnInstaller)), RemoveBackslashUnlessRoot(WizardDirValue)) = 0)
)
then
UninstallState := uiInconsistent;
end
else
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) or IsSecondaryUpdate then
begin
ForcePrimaryAppId := True;
Log('REDO UninstallState '+GetUninstallData('Inno Setup: App Path')+' // '+WizardDirValue);
if CompareText(RemoveBackslashUnlessRoot(RemoveQuotes(GetUninstallData('Inno Setup: App Path'))),
RemoveBackslashUnlessRoot(WizardDirValue)) = 0
then
UpdateUninstallInfo // use the plain installer
else
UninstallState := uiDone;
ForcePrimaryAppId := False;
end
else
UninstallState := uiDone;
end;
Log('UninstallState is now '+dbgsUiState(UninstallState)+', OldPath='+OldPath+' OldName='+OldName+' UnInstaller='+UnInstaller);
end;
// *** Display/Use Wizzard Page
procedure InitAskUninstall(s1, s2, s3, s4: String);
var
y: integer;
begin
wpLabel1.Caption := s1;
wpLabel2.Caption := s2;
wpLabel3.Caption := s3;
wpLabel4.Caption := s4;
wpLabel1.AdjustHeight;
wpLabel2.AdjustHeight;
wpLabel3.AdjustHeight;
wpLabel4.AdjustHeight;
wpLabel2.Top := wpLabel1.Top + wpLabel1.Height + ScaleY(5);
wpLabel3.Top := wpLabel2.Top + wpLabel2.Height + ScaleY(5);
wpLabel4.Top := wpLabel3.Top + wpLabel3.Height + ScaleY(5);
y := wpLabel4.Top + wpLabel4.Height + ScaleY(20);
if y > wpAskUnistall.SurfaceHeight - wpCheckBox.Height - wpButton.Height then
y := wpAskUnistall.SurfaceHeight - wpCheckBox.Height - wpButton.Height;
wpButton.Top := y;
end;
procedure UnInstUpdateGUI;
begin
UpdateUninstallInfo;
Log('UnInstUpdateGUI UninstallState='+dbgsUiState(UninstallState)+
' IsSecondaryUpdate='+dbgsBool(IsSecondaryUpdate)+
' Check='+dbgsBool((CheckSecondInstall <> nil) and (CheckSecondInstall.Checked))
);
WizardForm.NextButton.Enabled := (UninstallState = uiDone) or (UninstallState = uiDestNeeded) or wpCheckBox.Checked;
wpCheckBox.Enabled := not(UninstallState = uiDone);
wpButton.Enabled := not(UninstallState = uiDone);
end;
procedure ActivateAskUninst(Sender: TWizardPage);
begin
UnInstUpdateGUI;
end;
function SkipAskUninst(Sender: TWizardPage): Boolean;
begin
Log('SkipAskUninst UninstallState='+dbgsUiState(UninstallState)+
', OldPath='+OldPath+' OldName='+OldName+' UnInstaller='+UnInstaller +
' IsSecondaryUpdate='+dbgsBool(IsSecondaryUpdate)+
' Check='+dbgsBool((CheckSecondInstall <> nil) and (CheckSecondInstall.Checked))
);
Result := UninstallState = uiDone;
if Result Then exit;
UnInstUpdateGUI;
//UpdateUninstallInfo;
// OldName, Registry 'DisplayName'
// OldPath, Registry 'Inno Setup: App Path'
// UnInstaller
case UninstallState of
uiDestNeeded: begin
wpLabel2.Font.Color := clDefault;
wpCheckBox.Visible := False;
if IsSecondaryUpdate then
InitAskUninstall(Format(SaveCustomMessage('OldSecondInDestFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]))
else
InitAskUninstall(Format(SaveCustomMessage('OldInDestFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder2', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder3', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder4', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
end;
UIOtherNeeded: begin
wpLabel2.Font.Color := clRed;
wpLabel2.Font.Color := clRed;
wpCheckBox.Visible := True;
//if IsSecondaryUpdate then
// InitAskUninstall(Format(SaveCustomMessage('InOtherFolder1', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder2', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder3', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder4', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//else
InitAskUninstall(Format(SaveCustomMessage('OldInOtherFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//end;
end;
uiInconsistent: begin
wpLabel1.Font.Color := clRed;
wpLabel2.Font.Color := clRed;
wpCheckBox.Visible := True;
//if IsSecondaryUpdate then
// InitAskUninstall(Format(SaveCustomMessage('OldSecondInBadFolder1', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder2', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder3', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder4', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//else
InitAskUninstall(Format(SaveCustomMessage('OldInBadFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//end;
end;
end;
end;
procedure UnInstBtnClick(Sender: TObject);
var
s, UnInstaller: String;
b, FolderEmpty : Boolean;
i: integer;
begin
UninstallDoneState := UninstallState;
UninstallState := uiDone;
UnInstaller := RemoveQuotes(GetUninstallData('UninstallString'));
b := (UnInstaller <> '') and FileExists(UnInstaller);
if b then begin
LoadCFGFile(WizardDirValue, CFGFileForUninstDir);
UninstDir := WizardDirValue;
if UninstallState = uiInconsistent then
b := Exec(UnInstaller, '/VERBOSE /NORESTART','', SW_SHOW, ewWaitUntilTerminated, i)
else
b := Exec(UnInstaller, '/SILENT /NORESTART','', SW_SHOW, ewWaitUntilTerminated, i);
end;
if not b then
MsgBox('Uninstall failed.', mbConfirmation, MB_OK)
else begin
if (UninstallDoneState = uiDestNeeded) then
begin
FolderEmpty := IsDirEmpty(WizardDirValue);
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not(FolderEmpty) then begin
// Dir NOT empty, after uninstall
try
s := CustomMessage('FolderNotEmpty2');
except
s := 'The target folder is not empty.';
end;
MsgBox(s, mbConfirmation, MB_OK);
end;
end;
end;
UnInstUpdateGUI;
end;
procedure UnInstCheckboxClick(Sender: TObject);
begin
UnInstUpdateGUI;
end;
// *** Create Wizzard Page
procedure CreateUninstallWizardPage;
var
s, s2 : String;
begin
try
s := CustomMessage('AskUninstallTitle1');
s2 := CustomMessage('AskUninstallTitle2');
except
s := 'Previous Installation';
s2 := 'Do you want to run the uninstaller?';
end;
wpAskUnistall := CreateCustomPage(wpSelectDir, s, s2);
wpAskUnistall.OnShouldSkipPage := @SkipAskUninst;
wpAskUnistall.OnActivate := @ActivateAskUninst;
wpLabel1 := TNewStaticText.Create(wpAskUnistall);
wpLabel1.Parent := wpAskUnistall.Surface;
wpLabel1.Top := 0;
wpLabel1.Left := 0;
wpLabel1.Width := wpAskUnistall.SurfaceWidth;
wpLabel1.Autosize:= False;
wpLabel1.WordWrap := True;
wpLabel1.Caption := '';
wpLabel2 := TNewStaticText.Create(wpAskUnistall);
wpLabel2.Parent := wpAskUnistall.Surface;
wpLabel2.Left := 0;
wpLabel2.Width := wpAskUnistall.SurfaceWidth;
wpLabel2.Autosize:= False;
wpLabel2.WordWrap := True;
wpLabel2.Caption := '';
wpLabel3 := TNewStaticText.Create(wpAskUnistall);
wpLabel3.Parent := wpAskUnistall.Surface;
wpLabel3.Left := 0;
wpLabel3.Width := wpAskUnistall.SurfaceWidth;
wpLabel3.Autosize:= False;
wpLabel3.WordWrap := True;
wpLabel3.Caption := '';
wpLabel4 := TNewStaticText.Create(wpAskUnistall);
wpLabel4.Parent := wpAskUnistall.Surface;
wpLabel4.Left := 0;
wpLabel4.Width := wpAskUnistall.SurfaceWidth;
wpLabel4.Autosize:= False;
wpLabel4.WordWrap := True;
wpLabel4.Caption := '';
try
s := CustomMessage('BtnUninstall');
except
s := 'Uninstall';
end;
wpButton := TNewButton.Create(wpAskUnistall);
wpButton.Parent := wpAskUnistall.Surface;
wpButton.Width := ScaleX(80);
wpButton.Left := (wpAskUnistall.SurfaceWidth div 2) - ScaleX(40);
wpButton.Caption := s;
wpButton.OnClick := @UnInstBtnClick;
try
s := CustomMessage('ChkContinue');
except
s := 'Continue without uninstall';
end;
wpCheckBox := TNewCheckBox.Create(wpAskUnistall);
wpCheckBox.Parent := wpAskUnistall.Surface;
wpCheckBox.Top := wpAskUnistall.SurfaceHeight - wpCheckBox.Height - 1;
wpCheckBox.Width := wpAskUnistall.SurfaceWidth;
wpCheckBox.Caption := s;
wpCheckBox.OnClick := @UnInstCheckboxClick;
end;

View File

@ -266,354 +266,35 @@ Name: ru; MessagesFile: lazarus.ru.isl
Name: sl; MessagesFile: compiler:Languages\Slovenian.isl
[Code]
type
TUninstallState = (
uiUnknown,
UIDone, // There IS no uninstaller, OR it was already executed during this install
UIOtherNeeded, // The uninstaller ('Inno Setup: App Path') points to a different Path than "WizardFolder"
// Uninstall for OTHER folder NEEDED
uiDestNeeded, // Uninstaller for "WizardFolder" found
// Uninstall for DESTINATION folder NEEDED
uiInconsistent // Path of uninstaller and lazarus to be removed, do not match
);
TCfgFileState = (csNoFile, csUnreadable, csParsedOk);
var
wpAskUnistall: TWizardPage;
wpLabel1, wpLabel2, wpLabel3, wpLabel4: TNewStaticText;
wpCheckBox: TNewCheckBox;
wpButton: TNewButton;
wpAskConfDir: TInputDirWizardPage;
CheckSecondInstall: TCheckBox;
ForcePrimaryAppId: Boolean; // GetAppId should ignore secondary
// Additional Elements on TargetDir wizard page
CheckSecondInstall: TCheckBox; // Also used by GetAppId
CheckSecondLabel: TLabel;
UninstallState, UninstallDoneState: TUninstallState;
UnInstallerInAppPath: Boolean; // The uninstaller is in the directory that it will remove
OldPath, // Registry 'Inno Setup: App Path'
OldName, // Registry 'DisplayName'
UnInstaller: String; // Registry 'UninstallString'
PathEqual: Boolean;
ForcePrimaryAppId: BOolean;
IsSecondaryUpdate: Boolean; // Also used by GetAppId
IsSecondaryUpdate: Boolean;
SecondPCP: String;
NewCFGFile: TStringList;
SecondPCP: String; // used by common.GetPCPForDelete
UninstDir: String;
CFGFileForUninstDir: TStringList;
function dbgsBool(b: Boolean): String; begin Result := 'False'; if b then Result := 'True'; end;
function dbgsUiState(u: TUninstallState): String;
begin
case u of
uiUnknown: Result := 'uiUnknown';
UIDone: Result := 'UIDone';
UIOtherNeeded: Result := 'UIOtherNeeded';
uiDestNeeded: Result := 'uiDestNeeded';
uiInconsistent: Result := 'uiInconsistent';
end;
end;
#include "innoscript\common.pas"
#include "innoscript\conffile.pas" ; // Check/Load lazarus.cfg file // Create TStringList data
#include "innoscript\uninst.pas" ; // Uninstall of previous installation
#include "innoscript\about.pas" ; // Info displayed during install progress
#include "innoscript\secondary.pas"
function GetDefDir( def: String ) : String;
begin
if Pos( ' ', def ) > 0 then
begin
def := Copy( def, 1, Pos( ' ', def ) - 1 ) + '\NoFolderSpace';
end;
Result := def;
end;
procedure UpdateEnvironmentOptions();
var
FileName, Content: string;
s: Ansistring;
begin
FileName := ExpandConstant(CurrentFileName);
LoadStringFromFile(FileName, s);
Content := s;
StringChange(Content, '%Temp%', GetTempDir);
StringChange(Content, '%LazDir%', ExpandConstant('{app}'));
StringChange(Content, '%FpcBinDir%', ExpandConstant('{app}\fpc\{#FPCVersion}\bin\{#FPCFullTarget}\'));
SaveStringToFile(FileName, Content, False);
end;
function GetAppId(param:string): String;
var
s: String;
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) or IsSecondaryUpdate then
begin
// Secondary
s := RemoveBackslashUnlessRoot(Lowercase(WizardDirValue));
Result := 'lazarus_sec_'+GetSHA1OfString(s) + '_' + IntToStr(length(s));
end
else
Result := 'lazarus';
if ForcePrimaryAppId then
Result := 'lazarus';
Log('App-Id='+Result);
end;
function GetPCPForDelete(param:string): String;
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) then
begin
if SecondPCP = '' then
Result := AddBackslash(WizardDirValue) // some fallback
else
Result := AddBackslash(SecondPCP);
end
else
Result := ExpandConstant('{localappdata}\lazarus\');
Log('PrimConf for Delete='+Result);
end;
function IsDirEmpty(s: String): Boolean;
var
FindRec: TFindRec;
begin
Result := not DirExists(s);
if Result then exit;
SetCurrentDir(s);
Result := not FindFirst('*', FindRec);
if Result then exit;
if (FindRec.Name = '.') or (FindRec.Name = '..') then Result := not FindNext(FindRec);
if (not Result) and ((FindRec.Name = '.') or (FindRec.Name = '..')) then Result := not FindNext(FindRec);
FindClose(FindRec);
end;
function SaveCustomMessage(AMsgId, ADefaulText: String): String;
begin
try
Result := CustomMessage(AMsgId);
except
Result := ADefaulText;
end;
end;
function GetUninstallData(ARegName: String): String; // Get one entry from registry e.g. 'UninstallString'
var
Path: String;
begin
Path := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+GetAppId('')+'_is1');
Result := '';
if not RegQueryStringValue(HKLM, Path, ARegName, Result) then
RegQueryStringValue(HKCU, Path, ARegName, Result);
end;
procedure UpdateUninstallInfo;
begin
Log('Enter UninstallState '+dbgsUiState(UninstallState));
OldPath := '';
OldName := '';
UnInstaller := '';
PathEqual := False;
if UninstallState = uiDone then exit;
UnInstaller := RemoveQuotes(GetUninstallData('UninstallString'));
if (UnInstaller <> '') and FileExists(UnInstaller) then
begin
OldPath := RemoveQuotes((GetUninstallData('Inno Setup: App Path')));
OldName := GetUninstallData('DisplayName');
PathEqual := (OldPath <> '') and
(CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(WizardDirValue)) = 0);
if PathEqual then
UninstallState := uiDestNeeded
else
UninstallState := uiOtherNeeded;
UnInstallerInAppPath := (CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(ExtractFilePath(UnInstaller))) = 0);
if (not UnInstallerInAppPath) and
( (CompareText(RemoveBackslashUnlessRoot(OldPath), RemoveBackslashUnlessRoot(WizardDirValue)) = 0) or
(CompareText(RemoveBackslashUnlessRoot(ExtractFilePath(UnInstaller)), RemoveBackslashUnlessRoot(WizardDirValue)) = 0)
)
then
UninstallState := uiInconsistent;
end
else
begin
if ( (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) ) or IsSecondaryUpdate then
begin
ForcePrimaryAppId := True;
Log('REDO UninstallState '+GetUninstallData('Inno Setup: App Path')+' // '+WizardDirValue);
if CompareText(RemoveBackslashUnlessRoot(RemoveQuotes(GetUninstallData('Inno Setup: App Path'))),
RemoveBackslashUnlessRoot(WizardDirValue)) = 0
then
UpdateUninstallInfo // use the plain installer
else
UninstallState := uiDone;
ForcePrimaryAppId := False;
end
else
UninstallState := uiDone;
end;
Log('UninstallState is now '+dbgsUiState(UninstallState)+', OldPath='+OldPath+' OldName='+OldName+' UnInstaller='+UnInstaller);
end;
function LoadCFGFile(AFolder: String; var AList: TStringList): Boolean;
var
cfgfile: String;
begin
if AList = nil then
AList := TStringList.Create
else
AList.Clear;
cfgfile := AddBackslash(AFolder) + 'lazarus.cfg';
Result := FileExists(cfgfile);
if not Result then
exit;
AList.LoadFromFile(cfgfile);
end;
procedure CreateCFGFile(APCP: String; var AList: TStringList);
var
cfgfile: String;
begin
if AList = nil then
AList := TStringList.Create
else
AList.Clear;
AList.add('--primary-config-path=' + APCP);
end;
function ParseCFGFile(AFolder: String; var APrimConfDir: String): TCfgFileState;
var
s, cfgfile: String;
i: Integer;
l: TStringList;
begin
cfgfile := AddBackslash(AFolder) + 'lazarus.cfg';
Result := csNoFile;
if not FileExists(cfgfile) then begin
Log('ParseCFGFile not existent');
exit;
end;
Result := csUnreadable;
l := TStringList.Create;
l.LoadFromFile(cfgfile);
for i := 0 to l.Count - 1 do
if copy(l[i], 1, 6) = '--pcp=' then
s := copy(l[i], 7, length(l[i]))
else
if copy(l[i], 1, 22) = '--primary-config-path=' then
s := copy(l[i], 23, length(l[i]));
l.Free;
if s = '' then
exit;
if (s[1] = '"') and (s[length(s)] = '"') then
s := copy(s, 2, length(s)-2)
else
if (s[1] = '''') and (s[length(s)] = '''') then
s := copy(s, 2, length(s)-2)
if s = '' then
exit;
if (not FileExists(AddBackslash(s) + 'environmentoptions.xml')) and
(not IsDirEmpty(s))
then begin
Log('ParseCFGFile unreadable');
exit;
end;
Result := csParsedOk;
APrimConfDir := s;
Log('ParseCFGFile OK');
end;
procedure CurPageChanged(CurPageID: Integer);
var
m: TMemo;
begin
if CurPageID = wpInstalling then
begin
WizardForm.ProgressGauge.Parent.Handle;
m:= TMemo.Create(WizardForm);
m.Parent:=WizardForm.ProgressGauge.Parent;
m.Top := WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + 10;
m.Left := WizardForm.ProgressGauge.Left;
m.Width := WizardForm.ProgressGauge.Width ;
m.Height := WizardForm.ProgressGauge.Parent.Height - WizardForm.ProgressGauge.Height - WizardForm.ProgressGauge.Top - 15;
m.ReadOnly := True;
m.WordWrap := True;
m.ScrollBars := ssVertical;
m.Text := Format(CustomMessage('DuringInstall'), [#13#10]);
end;
if (CurPageID = wpSelectDir) and (CheckSecondInstall = nil) then
begin
WizardForm.DirEdit.Parent.Handle;
CheckSecondInstall := TCheckBox.Create(WizardForm);
CheckSecondInstall.Parent:=WizardForm.DirEdit.Parent;
CheckSecondInstall.Top := WizardForm.DirEdit.Top + WizardForm.DirEdit.Height + 10;
CheckSecondInstall.Left := WizardForm.DirEdit.Left;
CheckSecondInstall.Width := WizardForm.DirEdit.Parent.Width - WizardForm.DirEdit.Left;
CheckSecondInstall.Caption := CustomMessage('CheckSecondClick');
AddInfoComponentsToProgressWizzard;
CheckSecondLabel := TLabel.Create(WizardForm);
CheckSecondLabel.Parent:=WizardForm.DirEdit.Parent;
CheckSecondLabel.AutoSize := False;
CheckSecondLabel.WordWrap := True;
CheckSecondLabel.Top := CheckSecondInstall.Top + CheckSecondInstall.Height + 10;
CheckSecondLabel.Left := WizardForm.DirEdit.Left;
CheckSecondLabel.Width := WizardForm.DirEdit.Parent.Width - WizardForm.DirEdit.Left;
CheckSecondLabel.Height := WizardForm.DirEdit.Parent.Height - CheckSecondLabel.Top - 15;
CheckSecondLabel.Caption := CustomMessage('CheckSecondInfo');
end;
if (CurPageID = wpSelectDir) then
AddSecondaryCheckBoxToTargetDirWizzard;
if CurPageID = wpFinished then begin
if (CheckSecondInstall <> nil) and (CheckSecondInstall.Checked) then begin
if (NewCFGFile <> nil) then
try
NewCFGFile.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
ForceDirectories(SecondPCP);
except
MsgBox('Internal Error (1): Could not save CFG for secondary install', mbConfirmation, MB_OK);
end
else begin
MsgBox('Internal Error (2): Could not save CFG for secondary install', mbConfirmation, MB_OK);
end;
end
else
if (UninstallDoneState <> uiUnknown) and (IsSecondaryUpdate) and
(not FileExists(AddBackslash(WizardDirValue) + 'lazarus.cfg'))
then begin
// cfg was uninstalled / restore
if (NewCFGFile <> nil) then
try
NewCFGFile.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
except
MsgBox('Internal Error (3): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end
else
if (UninstDir = WizardDirValue) and (CFGFileForUninstDir <> nil) and
(CFGFileForUninstDir.count > 0)
then begin
try
CFGFileForUninstDir.SaveToFile(AddBackslash(WizardDirValue) + 'lazarus.cfg')
except
MsgBox('Internal Error (4): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end
end
else begin
MsgBox('Internal Error (5): Could not restore CFG for secondary install', mbConfirmation, MB_OK);
end;
end;
end;
if CurPageID = wpFinished then
CreateOrSaveConfigFile;
end;
function NextButtonClick(CurPage: Integer): Boolean;
@ -730,7 +411,6 @@ begin
Result := (IsSecondaryUpdate) or
( (CheckSecondInstall = nil) or (not CheckSecondInstall.Checked) );
end;
// UnInst uses: SkipAskUninst()
end;
@ -768,290 +448,17 @@ begin
ForcePrimaryAppId := False;
end;
procedure InitAskUninstall(s1, s2, s3, s4: String);
var
y: integer;
begin
wpLabel1.Caption := s1;
wpLabel2.Caption := s2;
wpLabel3.Caption := s3;
wpLabel4.Caption := s4;
wpLabel1.AdjustHeight;
wpLabel2.AdjustHeight;
wpLabel3.AdjustHeight;
wpLabel4.AdjustHeight;
wpLabel2.Top := wpLabel1.Top + wpLabel1.Height + ScaleY(5);
wpLabel3.Top := wpLabel2.Top + wpLabel2.Height + ScaleY(5);
wpLabel4.Top := wpLabel3.Top + wpLabel3.Height + ScaleY(5);
y := wpLabel4.Top + wpLabel4.Height + ScaleY(20);
if y > wpAskUnistall.SurfaceHeight - wpCheckBox.Height - wpButton.Height then
y := wpAskUnistall.SurfaceHeight - wpCheckBox.Height - wpButton.Height;
wpButton.Top := y;
end;
procedure UnInstUpdateGUI;
begin
UpdateUninstallInfo;
Log('UnInstUpdateGUI UninstallState='+dbgsUiState(UninstallState)+
' IsSecondaryUpdate='+dbgsBool(IsSecondaryUpdate)+
' Check='+dbgsBool((CheckSecondInstall <> nil) and (CheckSecondInstall.Checked))
);
WizardForm.NextButton.Enabled := (UninstallState = uiDone) or (UninstallState = uiDestNeeded) or wpCheckBox.Checked;
wpCheckBox.Enabled := not(UninstallState = uiDone);
wpButton.Enabled := not(UninstallState = uiDone);
end;
procedure ActivateAskUninst(Sender: TWizardPage);
begin
UnInstUpdateGUI;
end;
function SkipAskUninst(Sender: TWizardPage): Boolean;
begin
Log('SkipAskUninst UninstallState='+dbgsUiState(UninstallState)+
', OldPath='+OldPath+' OldName='+OldName+' UnInstaller='+UnInstaller +
' IsSecondaryUpdate='+dbgsBool(IsSecondaryUpdate)+
' Check='+dbgsBool((CheckSecondInstall <> nil) and (CheckSecondInstall.Checked))
);
Result := UninstallState = uiDone;
if Result Then exit;
UnInstUpdateGUI;
//UpdateUninstallInfo;
// OldName, Registry 'DisplayName'
// OldPath, Registry 'Inno Setup: App Path'
// UnInstaller
case UninstallState of
uiDestNeeded: begin
wpLabel2.Font.Color := clDefault;
wpCheckBox.Visible := False;
if IsSecondaryUpdate then
InitAskUninstall(Format(SaveCustomMessage('OldSecondInDestFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldSecondInDestFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]))
else
InitAskUninstall(Format(SaveCustomMessage('OldInDestFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder2', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder3', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInDestFolder4', ''), {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
end;
UIOtherNeeded: begin
wpLabel2.Font.Color := clRed;
wpLabel2.Font.Color := clRed;
wpCheckBox.Visible := True;
//if IsSecondaryUpdate then
// InitAskUninstall(Format(SaveCustomMessage('InOtherFolder1', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder2', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder3', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInOtherFolder4', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//else
InitAskUninstall(Format(SaveCustomMessage('OldInOtherFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInOtherFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//end;
end;
uiInconsistent: begin
wpLabel1.Font.Color := clRed;
wpLabel2.Font.Color := clRed;
wpCheckBox.Visible := True;
//if IsSecondaryUpdate then
// InitAskUninstall(Format(SaveCustomMessage('OldSecondInBadFolder1', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder2', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder3', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
// Format(SaveCustomMessage('OldSecondInBadFolder4', ''),
// {}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//else
InitAskUninstall(Format(SaveCustomMessage('OldInBadFolder1', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder2', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder3', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]),
Format(SaveCustomMessage('OldInBadFolder4', ''),
{}[#13#10, OldName, OldPath, UnInstaller, SecondPCP]));
//end;
end;
end;
end;
procedure UnInstBtnClick(Sender: TObject);
var
s, UnInstaller: String;
b, FolderEmpty : Boolean;
i: integer;
begin
UninstallDoneState := UninstallState;
UninstallState := uiDone;
UnInstaller := RemoveQuotes(GetUninstallData('UninstallString'));
b := (UnInstaller <> '') and FileExists(UnInstaller);
if b then begin
LoadCFGFile(WizardDirValue, CFGFileForUninstDir);
UninstDir := WizardDirValue;
if UninstallState = uiInconsistent then
b := Exec(UnInstaller, '/VERBOSE /NORESTART','', SW_SHOW, ewWaitUntilTerminated, i)
else
b := Exec(UnInstaller, '/SILENT /NORESTART','', SW_SHOW, ewWaitUntilTerminated, i);
end;
if not b then
MsgBox('Uninstall failed.', mbConfirmation, MB_OK)
else begin
if (UninstallDoneState = uiDestNeeded) then
begin
FolderEmpty := IsDirEmpty(WizardDirValue);
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not FolderEmpty then begin Sleep(500); FolderEmpty := IsDirEmpty(WizardDirValue); end;
if not(FolderEmpty) then begin
// Dir NOT empty, after uninstall
try
s := CustomMessage('FolderNotEmpty2');
except
s := 'The target folder is not empty.';
end;
MsgBox(s, mbConfirmation, MB_OK);
end;
end;
end;
UnInstUpdateGUI;
end;
procedure UnInstCheckboxClick(Sender: TObject);
begin
UnInstUpdateGUI;
end;
procedure InitializeWizard();
var
s, s2 : String;
begin
ForcePrimaryAppId := False;
try
s := CustomMessage('AskUninstallTitle1');
s2 := CustomMessage('AskUninstallTitle2');
except
s := 'Previous Installation';
s2 := 'Do you want to run the uninstaller?';
end;
wpAskUnistall := CreateCustomPage(wpSelectDir, s, s2);
wpAskUnistall.OnShouldSkipPage := @SkipAskUninst;
wpAskUnistall.OnActivate := @ActivateAskUninst;
wpLabel1 := TNewStaticText.Create(wpAskUnistall);
wpLabel1.Parent := wpAskUnistall.Surface;
wpLabel1.Top := 0;
wpLabel1.Left := 0;
wpLabel1.Width := wpAskUnistall.SurfaceWidth;
wpLabel1.Autosize:= False;
wpLabel1.WordWrap := True;
wpLabel1.Caption := '';
wpLabel2 := TNewStaticText.Create(wpAskUnistall);
wpLabel2.Parent := wpAskUnistall.Surface;
wpLabel2.Left := 0;
wpLabel2.Width := wpAskUnistall.SurfaceWidth;
wpLabel2.Autosize:= False;
wpLabel2.WordWrap := True;
wpLabel2.Caption := '';
wpLabel3 := TNewStaticText.Create(wpAskUnistall);
wpLabel3.Parent := wpAskUnistall.Surface;
wpLabel3.Left := 0;
wpLabel3.Width := wpAskUnistall.SurfaceWidth;
wpLabel3.Autosize:= False;
wpLabel3.WordWrap := True;
wpLabel3.Caption := '';
wpLabel4 := TNewStaticText.Create(wpAskUnistall);
wpLabel4.Parent := wpAskUnistall.Surface;
wpLabel4.Left := 0;
wpLabel4.Width := wpAskUnistall.SurfaceWidth;
wpLabel4.Autosize:= False;
wpLabel4.WordWrap := True;
wpLabel4.Caption := '';
try
s := CustomMessage('BtnUninstall');
except
s := 'Uninstall';
end;
wpButton := TNewButton.Create(wpAskUnistall);
wpButton.Parent := wpAskUnistall.Surface;
wpButton.Width := ScaleX(80);
wpButton.Left := (wpAskUnistall.SurfaceWidth div 2) - ScaleX(40);
wpButton.Caption := s;
wpButton.OnClick := @UnInstBtnClick;
InitializeUninstallInfo;
CreateUninstallWizardPage;
try
s := CustomMessage('ChkContinue');
except
s := 'Continue without uninstall';
end;
wpCheckBox := TNewCheckBox.Create(wpAskUnistall);
wpCheckBox.Parent := wpAskUnistall.Surface;
wpCheckBox.Top := wpAskUnistall.SurfaceHeight - wpCheckBox.Height - 1;
wpCheckBox.Width := wpAskUnistall.SurfaceWidth;
wpCheckBox.Caption := s;
wpCheckBox.OnClick := @UnInstCheckboxClick;
UninstallState := uiUnknown;
UninstallDoneState := uiUnknown;
/////////////////////////
wpAskConfDir := CreateInputDirPage(wpSelectDir,
CustomMessage('SecondConfCapt'), CustomMessage('SecondConfCapt2'),
CustomMessage('SecondConfBody'),
False, 'laz_conf');
wpAskConfDir.Add('Folder for config');
end;
CreateSecondaryConfFolderAndNameWizardPage;
function IsHKLMWriteable(): boolean;
begin
Result := IsAdminLoggedOn or IsPowerUserLoggedOn;
end;
function IsHKLMNotWriteable: boolean;
begin
Result := not IsHKLMWriteable();
end;
function GetAssociateDesc(const ext: string): string;
var
AmpersandPos: integer;
begin
Result := FmtMessage(CustomMessage('AssocFileExtension'), ['Lazarus',ext]);
AmpersandPos := pos('&', Result);
if AmpersandPos>0 then
Delete(Result, AmpersandPos, 1);
end;
//function InitializeUninstall(): Boolean;