feat(windows): automatic updates option to config reg

This commit is contained in:
rc-swag 2024-09-09 15:51:32 +10:00
parent eff8a8828c
commit bfe1b45983
17 changed files with 256 additions and 33 deletions

View file

@ -313,8 +313,10 @@ const
SRegValue_ActiveProject_Filename = 'project filename';
SRegValue_ActiveProject_SourcePath = 'source path';
SRegValue_AutomaticUpdates = 'automatic updates'; //CU
SRegValue_CheckForUpdates = 'check for updates'; // CU
SRegValue_LastUpdateCheckTime = 'last update check time'; // CU
SRegValue_ApplyNow = 'apply now'; // CU Start the install now even thought it will require an update
SRegValue_UpdateCheck_UseProxy = 'update check use proxy'; // CU
SRegValue_UpdateCheck_ProxyHost = 'update check proxy host'; // CU

View file

@ -388,6 +388,11 @@
<!-- Introduced: 7.0.230.0 -->
<string name="koShowWelcome" comment="Startup options - show/hide welcome screen">Show welcome screen</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 18.0.96.0 -->
<string name="koAutomaticUpdate" comment="Automatically download updates ready to install">Automatically download updates ready to install</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 7.0.230.0 -->

View file

@ -184,7 +184,8 @@ uses
Keyman.System.UpdateStateMachine in 'main\Keyman.System.UpdateStateMachine.pas',
Keyman.System.DownloadUpdate in 'main\Keyman.System.DownloadUpdate.pas',
Keyman.System.ExecutionHistory in '..\..\..\..\common\windows\delphi\general\Keyman.System.ExecutionHistory.pas',
UfrmStartInstall in 'main\UfrmStartInstall.pas' {Form1};
UfrmStartInstallNow in 'main\UfrmStartInstallNow.pas',
UfrmStartInstall in 'main\UfrmStartInstall.pas';
{$R VERSION.RES}
{$R manifest.res}

View file

@ -360,8 +360,12 @@
<DCCReference Include="main\Keyman.System.UpdateStateMachine.pas"/>
<DCCReference Include="main\Keyman.System.DownloadUpdate.pas"/>
<DCCReference Include="..\..\..\..\common\windows\delphi\general\Keyman.System.ExecutionHistory.pas"/>
<DCCReference Include="main\UfrmStartInstallNow.pas">
<Form>frmInstallNow</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="main\UfrmStartInstall.pas">
<Form>Form1</Form>
<Form>frmStartInstall</Form>
<FormType>dfm</FormType>
</DCCReference>
<None Include="Profiling\AQtimeModule1.aqt"/>

View file

@ -33,6 +33,7 @@ uses
httpuploader,
Keyman.System.UpdateCheckResponse,
UfrmStartInstall,
UfrmStartInstallNow,
Keyman.System.ExecutionHistory,
UfrmDownloadProgress;
@ -215,7 +216,7 @@ type
TUpdateStateMachine = class
private
FForce: Boolean;
FAuto: Boolean;
FAutomaticUpdate: Boolean;
FParams: TUpdateStateMachineParams;
FErrorMessage: string;
DownloadTempPath: string;
@ -247,6 +248,9 @@ type
function checkUpdateSchedule : Boolean;
function SetRegistryState (Update : TUpdateState): Boolean;
function GetAutomaticUpdate: Boolean;
function SetApplyNow(Value : Boolean): Boolean;
function GetApplyNow: Boolean;
protected
property State: TStateClass read GetState write SetState;
@ -325,7 +329,7 @@ begin
FParams.Result := oucUnknown;
FForce := AForce;
FAuto := True; // Default to automatically check, download, and install
FAutomaticUpdate := GetAutomaticUpdate;
FIdle := IdleState.Create(Self);
FUpdateAvailable := UpdateAvailableState.Create(Self);
FDownloading := DownloadingState.Create(Self);
@ -408,9 +412,9 @@ begin
try
Registry.RootKey := HKEY_CURRENT_USER;
KL.Log('SetRegistryState State Entry');
if not Registry.OpenKey(SRegKey_KeymanEngine_LM, True) then
if not Registry.OpenKey(SRegKey_KeymanEngine_CU, True) then
begin
KL.Log('Failed to open registry key: ' + SRegKey_KeymanEngine_LM);
KL.Log('Failed to open registry key: ' + SRegKey_KeymanEngine_CU);
Exit;
end;
@ -444,7 +448,7 @@ begin
Registry := TRegistryErrorControlled.Create; // I2890
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKeyReadOnly(SRegKey_KeymanEngine_LM) and Registry.ValueExists(SRegValue_Update_State) then
if Registry.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and Registry.ValueExists(SRegValue_Update_State) then
begin
UpdateState := TUpdateState(GetEnumValue(TypeInfo(TUpdateState), Registry.ReadString(SRegValue_Update_State)));
KL.Log('CheckRegistryState State is:[' + Registry.ReadString(SRegValue_Update_State) + ']');
@ -461,6 +465,77 @@ begin
Result := UpdateState;
end;
function TUpdateStateMachine.GetAutomaticUpdate: Boolean; // I2329
var
Registry: TRegistryErrorControlled;
begin
// check the registry value
Registry := TRegistryErrorControlled.Create; // I2890
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and Registry.ValueExists(SRegValue_AutomaticUpdates) then
begin
Result := Registry.ReadBool(SRegValue_AutomaticUpdates);
end
else
begin
Result := True; // Default
end;
finally
Registry.Free;
end;
end;
function TUpdateStateMachine.SetApplyNow(Value : Boolean): Boolean;
var
Registry: TRegistryErrorControlled;
begin
Result := False;
Registry := TRegistryErrorControlled.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if not Registry.OpenKey(SRegKey_KeymanEngine_CU, True) then
begin
Exit;
end;
try
Registry.WriteBool(SRegValue_ApplyNow, Value);
Result := True;
except
on E: Exception do
begin
KL.Log('Failed to write to registry: ' + E.Message);
end;
end;
finally
Registry.Free;
end;
end;
function TUpdateStateMachine.GetApplyNow: Boolean;
var
Registry: TRegistryErrorControlled;
begin
// check the registry value
Registry := TRegistryErrorControlled.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and Registry.ValueExists(SRegValue_ApplyNow) then
begin
Result := Registry.ReadBool(SRegValue_ApplyNow);
end
else
begin
Result := False; // Default
end;
finally
Registry.Free;
end;
end;
function TUpdateStateMachine.CheckUpdateSchedule: Boolean;
var
RegistryErrorControlled :TRegistryErrorControlled;
@ -728,7 +803,7 @@ procedure UpdateAvailableState.Enter;
begin
// Enter UpdateAvailableState
bucStateContext.SetRegistryState(usUpdateAvailable);
if bucStateContext.FAuto then
if bucStateContext.FAutomaticUpdate then
begin
StartDownloadProcess;
end;
@ -746,7 +821,7 @@ end;
function UpdateAvailableState.HandleKmShell;
begin
if bucStateContext.FAuto then
if bucStateContext.FAutomaticUpdate then
begin
// we will use a new kmshell process to enable
// the download as background process.
@ -766,8 +841,20 @@ begin
end;
procedure UpdateAvailableState.HandleInstallNow;
var
frmStartInstallNow : TfrmStartInstallNow;
begin
ChangeState(DownloadingState);
// If user decides NOT to install now stay in UpdateAvailable State
frmStartInstallNow := TfrmStartInstallNow.Create(nil);
try
if frmStartInstallNow.ShowModal = mrOk then
begin
bucStateContext.SetApplyNow(True);
ChangeState(InstallingState)
end
finally
frmStartInstallNow.Free;
end;
end;
function UpdateAvailableState.StateName;
@ -793,10 +880,17 @@ begin
begin
if HasKeymanRun then
begin
ChangeState(WaitingRestartState);
if bucStateContext.GetApplyNow then
begin
bucStateContext.SetApplyNow(False);
ChangeState(InstallingState);
end
else
ChangeState(WaitingRestartState);
end
else
begin
bucStateContext.SetApplyNow(False);
ChangeState(InstallingState);
end;
end
@ -837,7 +931,8 @@ end;
procedure DownloadingState.HandleInstallNow;
begin
// Already downloading set the registry apply now
bucStateContext.SetApplyNow(True);
end;
function DownloadingState.StateName;
@ -948,11 +1043,25 @@ begin
end;
procedure WaitingRestartState.HandleInstallNow;
var
frmStartInstallNow : TfrmStartInstallNow;
begin
// TODO: Check if keyman has run, and error trying to install
// now when windows needs a restart ask the user if they
// want to restart now, if users says no stay in this (waitingrestart) state
ChangeState(InstallingState);
// If user decides not to install now stay in WaitingRestart State
frmStartInstallNow := TfrmStartInstallNow.Create(nil);
try
if frmStartInstallNow.ShowModal = mrOk then
begin
bucStateContext.SetApplyNow(True);
ChangeState(InstallingState)
end
finally
frmStartInstallNow.Free;
end;
end;
function WaitingRestartState.StateName;

View file

@ -1,18 +1,18 @@
(*
Name: UImportOlderVersionSettings
Copyright: Copyright (C) 2003-2017 SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 22 Feb 2011
Modified Date: 3 Jun 2014
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 22 Feb 2011 - mcdurdin - I2651 - Install does not set desired default options
22 Feb 2011 - mcdurdin - I2753 - Firstrun crashes because start with windows and auto update check options are set in Engine instead of Desktop
03 May 2011 - mcdurdin - I2890 - Record diagnostic data when encountering registry errors
@ -24,7 +24,7 @@ unit UImportOlderVersionSettings;
interface
function FirstRunInstallDefaults(DoDefaults,DoStartWithWindows,DoCheckForUpdates: Boolean; FDisablePackages, FDefaultUILanguage: string; DoAutomaticallyReportUsage: Boolean): Boolean; // I2753
function FirstRunInstallDefaults(DoDefaults,DoStartWithWindows,DoCheckForUpdates,DoAutomaticUpdates: Boolean; FDisablePackages, FDefaultUILanguage: string; DoAutomaticallyReportUsage: Boolean): Boolean; // I2753
implementation
@ -43,7 +43,7 @@ uses
RegistryKeys,
UImportOlderKeyboardUtils;
function FirstRunInstallDefaults(DoDefaults,DoStartWithWindows,DoCheckForUpdates: Boolean; FDisablePackages, FDefaultUILanguage: string; DoAutomaticallyReportUsage: Boolean): Boolean; // I2753
function FirstRunInstallDefaults(DoDefaults,DoStartWithWindows,DoCheckForUpdates,DoAutomaticUpdates: Boolean; FDisablePackages, FDefaultUILanguage: string; DoAutomaticallyReportUsage: Boolean): Boolean; // I2753
var
n, I: Integer;
v: Integer;
@ -136,6 +136,7 @@ begin
if DoStartWithWindows then kmcom.Options['koStartWithWindows'].Value := True; // I2753
if DoCheckForUpdates then kmcom.Options['koCheckForUpdates'].Value := True; // I2753
if DoAutomaticUpdates then kmcom.Options['koAutomaticUpdate'].Value := True;
if DoAutomaticallyReportUsage then kmcom.Options['koAutomaticallyReportUsage'].Value := True;

View file

@ -0,0 +1,50 @@
object frmStartInstallNow: TfrmStartInstallNow
Left = 0
Top = 0
Caption = 'Keyman Update'
ClientHeight = 225
ClientWidth = 425
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object InstallUpdate: TLabel
Left = 69
Top = 72
Width = 296
Height = 38
Caption =
'Installing Now will require a Keyman and Windows Restart Continu' +
'e?'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
WordWrap = True
end
object Install: TButton
Left = 228
Top = 184
Width = 75
Height = 25
Caption = 'Install'
TabOrder = 0
OnClick = InstallClick
end
object Later: TButton
Left = 336
Top = 184
Width = 75
Height = 25
Caption = 'Close'
TabOrder = 1
OnClick = LaterClick
end
end

View file

@ -0,0 +1,38 @@
unit UfrmStartInstallNow;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, UserMessages, StdCtrls, ExtCtrls, UfrmKeymanBase;
type
TfrmStartInstallNow = class(TfrmKeymanBase)
Install: TButton;
Later: TButton;
InstallUpdate: TLabel;
procedure InstallClick(Sender: TObject);
procedure LaterClick(Sender: TObject);
private
public
end;
var
frmStartInstall: TfrmStartInstallNow;
implementation
{$R *.dfm}
procedure TfrmStartInstallNow.InstallClick(Sender: TObject);
begin
ModalResult := mrOk;
end;
procedure TfrmStartInstallNow.LaterClick(Sender: TObject);
begin
ModalResult := mrCancel;
end;
end.

View file

@ -658,6 +658,7 @@ begin
Pos('installdefaults', FQuery) > 0,
Pos('startwithwindows', FQuery) > 0,
Pos('checkforupdates', FQuery) > 0,
Pos('automaticupdates', FQuery) > 0,
FDisablePackages,
FDefaultUILanguage,
Pos('automaticallyreportusage', FQuery) > 0); // I2651, I2753

View file

@ -412,6 +412,11 @@
<!-- Introduced: 7.0.230.0 -->
<string name="koShowWelcome" comment="Startup options - show/hide welcome screen">Show welcome screen</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 18.0.96.0 -->
<string name="koAutomaticUpdate" comment="Automatically download updates ready to install">Automatically download updates ready to install</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 7.0.230.0 -->

View file

@ -82,7 +82,7 @@ type
InstallSuccess: Boolean);
function InstallMSI(msiLocation: TInstallInfoFileLocation; var InstallDefaults: Boolean; ContinueSetup: Boolean): Boolean;
procedure ConfigFirstRun(StartKeyman,StartWithWindows,
CheckForUpdates,StartDisabled,StartWithConfiguration,InstallDefaults,
CheckForUpdates,AutomaticUpdates,StartDisabled,StartWithConfiguration,InstallDefaults,
AutomaticallyReportUsage: Boolean);
procedure PrepareForReboot(res: Cardinal; InstallDefaults: Boolean);
function RestartWindows: Boolean;
@ -101,7 +101,7 @@ type
destructor Destroy; override;
procedure CheckInternetConnectedState;
function DoInstall(Handle: THandle;
StartAfterInstall, StartWithWindows, CheckForUpdates, StartDisabled,
StartAfterInstall, StartWithWindows, CheckForUpdates, AutomaticUpdates, StartDisabled,
StartWithConfiguration, InstallDefaults, AutomaticallyReportUsage, ContinueSetup: Boolean): Boolean;
procedure LogError(const msg: WideString; ShowDialogIfNotSilent: Boolean = True);
procedure LogInfo(const msg: string; ShowDialogIfNotSilent: Boolean = False);
@ -194,7 +194,7 @@ begin
end;
function TRunTools.DoInstall(Handle: THandle;
StartAfterInstall, StartWithWindows, CheckForUpdates, StartDisabled,
StartAfterInstall, StartWithWindows, CheckForUpdates, AutomaticUpdates, StartDisabled,
StartWithConfiguration, InstallDefaults, AutomaticallyReportUsage, ContinueSetup: Boolean): Boolean;
var
msiLocation: TInstallInfoFileLocation;
@ -224,7 +224,7 @@ begin
Exit(False);
end;
ConfigFirstRun(StartAfterInstall,StartWithWindows,CheckForUpdates,
ConfigFirstRun(StartAfterInstall,StartWithWindows,CheckForUpdates,AutomaticUpdates,
StartDisabled,StartWithConfiguration,InstallDefaults,AutomaticallyReportUsage);
Result := True;
@ -588,7 +588,7 @@ begin
end;
end;
procedure TRunTools.ConfigFirstRun(StartKeyman,StartWithWindows,CheckForUpdates,
procedure TRunTools.ConfigFirstRun(StartKeyman,StartWithWindows,CheckForUpdates,AutomaticUpdates,
StartDisabled,StartWithConfiguration,InstallDefaults,AutomaticallyReportUsage: Boolean);
var
i: Integer;
@ -686,6 +686,7 @@ begin
if StartWithWindows then s := s + 'StartWithWindows,';
if CheckForUpdates then s := s + 'CheckForUpdates,';
if AutomaticUpdates then s := s + 'AutomaticUpdates,';
if AutomaticallyReportUsage then s := s + 'AutomaticallyReportUsage,';
if InstallDefaults then

View file

@ -113,6 +113,7 @@ type
FCanUpgrade9: Boolean;
FCanUpgrade10: Boolean;
FCheckForUpdates: Boolean;
FAutomaticUpdates: Boolean;
FStartAfterInstall: Boolean;
FStartWithWindows: Boolean;
FAutomaticallyReportUsage: Boolean;
@ -523,7 +524,7 @@ begin
SetupMSI; // I2644
if GetRunTools.DoInstall(Handle, FStartAfterInstall, FStartWithWindows, FCheckForUpdates,
FInstallInfo.StartDisabled, FInstallInfo.StartWithConfiguration, FInstallDefaults,
FAutomaticUpdates, FInstallInfo.StartDisabled, FInstallInfo.StartWithConfiguration, FInstallDefaults,
FAutomaticallyReportUsage, FContinueSetup) then
begin
if not Silent and not FStartAfterInstall then // I2610
@ -1032,6 +1033,7 @@ procedure TfrmRunDesktop.GetDefaultSettings; // I2651
begin
FStartWithWindows := True; // I2607
FCheckForUpdates := True; // I2609
FAutomaticUpdates := True;
try
with CreateHKCURegistry do // I2749
@ -1041,6 +1043,8 @@ begin
FCheckForUpdates := ValueExists(SRegValue_CheckForUpdates) and ReadBool(SRegValue_CheckForUpdates);
FStartWithWindows := ValueExists(SRegValue_UpgradeRunKeyman) or
(OpenKeyReadOnly('\' + SRegKey_WindowsRun_CU) and ValueExists(SRegValue_WindowsRun_Keyman));
FAutomaticUpdates := ValueExists(SRegValue_AutomaticUpdates) and ReadBool(SRegValue_AutomaticUpdates);
end
else if FCanUpgrade10 and OpenKeyReadOnly(SRegKey_KeymanEngine100_ProductOptions_Desktop_CU) then // I4293
begin

View file

@ -113,7 +113,7 @@ uses
sentry in '..\..\..\..\common\windows\delphi\ext\sentry\sentry.pas',
Keyman.System.KeymanSentryClient in '..\..\..\..\common\windows\delphi\general\Keyman.System.KeymanSentryClient.pas',
Keyman.System.LocaleStrings in '..\..\global\delphi\cust\Keyman.System.LocaleStrings.pas',
Keyman.System.ExecuteHistory in '..\..\..\..\common\windows\delphi\general\Keyman.System.ExecuteHistory.pas';
Keyman.System.ExecutionHistory in '..\..\..\..\common\windows\delphi\general\Keyman.System.ExecutionHistory.pas';
{$R ICONS.RES}
{$R VERSION.RES}

View file

@ -238,7 +238,7 @@
<DCCReference Include="..\..\..\..\common\windows\delphi\ext\sentry\sentry.pas"/>
<DCCReference Include="..\..\..\..\common\windows\delphi\general\Keyman.System.KeymanSentryClient.pas"/>
<DCCReference Include="..\..\global\delphi\cust\Keyman.System.LocaleStrings.pas"/>
<DCCReference Include="..\..\..\..\common\windows\delphi\general\Keyman.System.ExecuteHistory.pas"/>
<DCCReference Include="..\..\..\..\common\windows\delphi\general\Keyman.System.ExecutionHistory.pas"/>
<None Include="Profiling\AQtimeModule1.aqt"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>

View file

@ -47,7 +47,7 @@ uses
UfrmKeyman7Main,
UserMessages,
Klog,
Keyman.System.ExecuteHistory;
Keyman.System.ExecutionHistory;
function ValidateParameters(var FCommand: Integer): Boolean; forward;
function PassParametersToRunningInstance(FCommand: Integer): Boolean; forward;

View file

@ -121,14 +121,15 @@ type
GroupName: string;
end;
const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552
const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552
// Global options
(opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'),
(opt: koSwitchLanguageForAllApplications; RegistryName: SRegValue_SwitchLanguageForAllApplications; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I2277 // I4393
(opt: koAltGrCtrlAlt; RegistryName: SRegValue_AltGrCtrlAlt; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'),
(opt: koShowHints; RegistryName: SRegValue_EnableHints; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'),
(opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'),
(opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'),
(opt: koAutomaticUpdate; RegistryName: SRegValue_AutomaticUpdates; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'),
(opt: koAutomaticallyReportErrors; RegistryName: SRegValue_AutomaticallyReportErrors; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I4393
(opt: koAutomaticallyReportUsage; RegistryName: SRegValue_AutomaticallyReportUsage; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I4393

View file

@ -7,6 +7,7 @@ type
// General options
koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress,
koShowHints, // I1256
koAutomaticUpdate,
// Startup options
koTestKeymanFunctioning,
koStartWithWindows,