2026-04-22 07:31:54 +08:00
|
|
|
using Avalonia.Threading;
|
|
|
|
|
using LanMountainDesktop.Launcher.Views;
|
|
|
|
|
|
2026-05-28 10:43:30 +08:00
|
|
|
namespace LanMountainDesktop.Launcher.Oobe;
|
2026-04-22 07:31:54 +08:00
|
|
|
|
|
|
|
|
internal sealed class WelcomeOobeStep : IOobeStep
|
|
|
|
|
{
|
Harden OOBE, launch-source and elevation flow
Introduce a per-user OOBE state model and hardened launch/elevation handling. Adds OobeStateFile/OobeLaunchDecision models, OobeStateService (persisting %LOCALAPPDATA%/.launcher/state/oobe-state.json), and LauncherExecutionContext to capture elevation and user SID. CommandContext now normalizes/infers launch-source values (normal, postinstall, apply-update, plugin-install, debug-preview) and exposes maintenance checks. LauncherFlowCoordinator propagates richer launcher context details for diagnostics and suppresses OOBE for elevated/maintenance contexts. PluginInstallerService avoids requesting elevation for user-scoped installs and returns a clear error when installation target is outside the current user's LocalAppData. LauncherClient maps and surfaces result codes, UpdateWorkflow and installer invocation now pass explicit --launch-source values, and WelcomeOobeStep persists OOBE completion via the new service. Adds unit tests (CommandContext, OobeStateService, PluginInstallerService), docs/specs/checklists for the contract, and makes internals visible to tests.
2026-04-22 09:25:22 +08:00
|
|
|
private readonly CommandContext _context;
|
2026-04-22 07:31:54 +08:00
|
|
|
private readonly OobeStateService _oobeStateService;
|
2026-06-05 11:08:11 +08:00
|
|
|
private readonly DataLocationResolver _dataLocationResolver;
|
2026-04-22 07:31:54 +08:00
|
|
|
|
2026-06-05 11:08:11 +08:00
|
|
|
public WelcomeOobeStep(
|
|
|
|
|
OobeStateService oobeStateService,
|
|
|
|
|
CommandContext context,
|
|
|
|
|
DataLocationResolver dataLocationResolver)
|
2026-04-22 07:31:54 +08:00
|
|
|
{
|
|
|
|
|
_oobeStateService = oobeStateService;
|
Harden OOBE, launch-source and elevation flow
Introduce a per-user OOBE state model and hardened launch/elevation handling. Adds OobeStateFile/OobeLaunchDecision models, OobeStateService (persisting %LOCALAPPDATA%/.launcher/state/oobe-state.json), and LauncherExecutionContext to capture elevation and user SID. CommandContext now normalizes/infers launch-source values (normal, postinstall, apply-update, plugin-install, debug-preview) and exposes maintenance checks. LauncherFlowCoordinator propagates richer launcher context details for diagnostics and suppresses OOBE for elevated/maintenance contexts. PluginInstallerService avoids requesting elevation for user-scoped installs and returns a clear error when installation target is outside the current user's LocalAppData. LauncherClient maps and surfaces result codes, UpdateWorkflow and installer invocation now pass explicit --launch-source values, and WelcomeOobeStep persists OOBE completion via the new service. Adds unit tests (CommandContext, OobeStateService, PluginInstallerService), docs/specs/checklists for the contract, and makes internals visible to tests.
2026-04-22 09:25:22 +08:00
|
|
|
_context = context;
|
2026-06-05 11:08:11 +08:00
|
|
|
_dataLocationResolver = dataLocationResolver;
|
2026-04-22 07:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-05 11:08:11 +08:00
|
|
|
public async Task<OobeStepResult> RunAsync(CancellationToken cancellationToken)
|
2026-04-22 07:31:54 +08:00
|
|
|
{
|
|
|
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
|
|
|
|
|
|
OobeWindow? window = null;
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
window = new OobeWindow();
|
|
|
|
|
window.Show();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (window is null)
|
|
|
|
|
{
|
2026-06-05 11:08:11 +08:00
|
|
|
return BuildCancelledResult("OOBE window could not be created.");
|
2026-04-22 07:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-05 11:08:11 +08:00
|
|
|
var draft = await window.WaitForCompletionAsync().ConfigureAwait(false);
|
|
|
|
|
if (draft is null)
|
|
|
|
|
{
|
|
|
|
|
Logger.Info("OOBE was cancelled before completion; Host launch will be skipped.");
|
|
|
|
|
return BuildCancelledResult("OOBE was cancelled before completion.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var completion = new OobeSessionCommitService(
|
|
|
|
|
_dataLocationResolver,
|
|
|
|
|
_oobeStateService,
|
|
|
|
|
_context)
|
|
|
|
|
.Commit(draft);
|
Harden OOBE, launch-source and elevation flow
Introduce a per-user OOBE state model and hardened launch/elevation handling. Adds OobeStateFile/OobeLaunchDecision models, OobeStateService (persisting %LOCALAPPDATA%/.launcher/state/oobe-state.json), and LauncherExecutionContext to capture elevation and user SID. CommandContext now normalizes/infers launch-source values (normal, postinstall, apply-update, plugin-install, debug-preview) and exposes maintenance checks. LauncherFlowCoordinator propagates richer launcher context details for diagnostics and suppresses OOBE for elevated/maintenance contexts. PluginInstallerService avoids requesting elevation for user-scoped installs and returns a clear error when installation target is outside the current user's LocalAppData. LauncherClient maps and surfaces result codes, UpdateWorkflow and installer invocation now pass explicit --launch-source values, and WelcomeOobeStep persists OOBE completion via the new service. Adds unit tests (CommandContext, OobeStateService, PluginInstallerService), docs/specs/checklists for the contract, and makes internals visible to tests.
2026-04-22 09:25:22 +08:00
|
|
|
if (!completion.Success)
|
|
|
|
|
{
|
|
|
|
|
Logger.Warn(
|
2026-06-05 11:08:11 +08:00
|
|
|
$"OOBE session was not persisted. ResultCode='{completion.ResultCode}'; " +
|
Harden OOBE, launch-source and elevation flow
Introduce a per-user OOBE state model and hardened launch/elevation handling. Adds OobeStateFile/OobeLaunchDecision models, OobeStateService (persisting %LOCALAPPDATA%/.launcher/state/oobe-state.json), and LauncherExecutionContext to capture elevation and user SID. CommandContext now normalizes/infers launch-source values (normal, postinstall, apply-update, plugin-install, debug-preview) and exposes maintenance checks. LauncherFlowCoordinator propagates richer launcher context details for diagnostics and suppresses OOBE for elevated/maintenance contexts. PluginInstallerService avoids requesting elevation for user-scoped installs and returns a clear error when installation target is outside the current user's LocalAppData. LauncherClient maps and surfaces result codes, UpdateWorkflow and installer invocation now pass explicit --launch-source values, and WelcomeOobeStep persists OOBE completion via the new service. Adds unit tests (CommandContext, OobeStateService, PluginInstallerService), docs/specs/checklists for the contract, and makes internals visible to tests.
2026-04-22 09:25:22 +08:00
|
|
|
$"Error='{completion.ErrorMessage}'.");
|
2026-06-05 11:08:11 +08:00
|
|
|
return OobeStepResult.Complete(LaunchResultBuilder.Build(
|
|
|
|
|
false,
|
|
|
|
|
"oobe",
|
|
|
|
|
completion.ResultCode,
|
|
|
|
|
"OOBE settings could not be saved.",
|
|
|
|
|
errorMessage: completion.ErrorMessage));
|
Harden OOBE, launch-source and elevation flow
Introduce a per-user OOBE state model and hardened launch/elevation handling. Adds OobeStateFile/OobeLaunchDecision models, OobeStateService (persisting %LOCALAPPDATA%/.launcher/state/oobe-state.json), and LauncherExecutionContext to capture elevation and user SID. CommandContext now normalizes/infers launch-source values (normal, postinstall, apply-update, plugin-install, debug-preview) and exposes maintenance checks. LauncherFlowCoordinator propagates richer launcher context details for diagnostics and suppresses OOBE for elevated/maintenance contexts. PluginInstallerService avoids requesting elevation for user-scoped installs and returns a clear error when installation target is outside the current user's LocalAppData. LauncherClient maps and surfaces result codes, UpdateWorkflow and installer invocation now pass explicit --launch-source values, and WelcomeOobeStep persists OOBE completion via the new service. Adds unit tests (CommandContext, OobeStateService, PluginInstallerService), docs/specs/checklists for the contract, and makes internals visible to tests.
2026-04-22 09:25:22 +08:00
|
|
|
}
|
2026-04-22 07:31:54 +08:00
|
|
|
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
if (window.IsVisible)
|
|
|
|
|
{
|
|
|
|
|
window.Close();
|
|
|
|
|
}
|
|
|
|
|
});
|
2026-06-05 11:08:11 +08:00
|
|
|
|
|
|
|
|
return OobeStepResult.Continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static OobeStepResult BuildCancelledResult(string message)
|
|
|
|
|
{
|
|
|
|
|
return OobeStepResult.Complete(LaunchResultBuilder.Build(
|
|
|
|
|
false,
|
|
|
|
|
"oobe",
|
|
|
|
|
"oobe_cancelled",
|
|
|
|
|
message));
|
2026-04-22 07:31:54 +08:00
|
|
|
}
|
|
|
|
|
}
|