mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 05:18:00 +02:00
Win-Installer: refactor, move some parts of the script into include files
git-svn-id: trunk@42526 -
This commit is contained in:
parent
46fe5c5c38
commit
4e1b98a5f2
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -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
|
||||
|
21
tools/install/win/innoscript/about.pas
Normal file
21
tools/install/win/innoscript/about.pas
Normal 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;
|
||||
|
109
tools/install/win/innoscript/common.pas
Normal file
109
tools/install/win/innoscript/common.pas
Normal 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;
|
||||
|
||||
|
||||
|
83
tools/install/win/innoscript/conffile.pas
Normal file
83
tools/install/win/innoscript/conffile.pas
Normal 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;
|
||||
|
83
tools/install/win/innoscript/secondary.pas
Normal file
83
tools/install/win/innoscript/secondary.pas
Normal 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;
|
||||
|
368
tools/install/win/innoscript/uninst.pas
Normal file
368
tools/install/win/innoscript/uninst.pas
Normal 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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user