private async void StartupOrchestratorAsync(IActivatedEventArgs e, StartKind kind) { DebugWrite($"kind:{kind} previous:{e.PreviousExecutionState}"); if (_originalActivatedArgs == null) { _originalActivatedArgs = e; // if resume tries to launch, don't continue on // StartupOrchestratorAsync will be called twice if (_originalActivatedArgs == null) { OnResuming(this, null, AppExecutionState.Terminated); return; } PreviousExecutionState = e.PreviousExecutionState; PrelaunchActivated = (e as LaunchActivatedEventArgs)?.PrelaunchActivated ?? false; } // is the kind really right? if (kind == StartKind.Launch && CurrentStateHistory.ContainsValue(BootstrapperStates.Launching)) { kind = StartKind.Activate; } else if (kind == StartKind.Launch && e.PreviousExecutionState == ApplicationExecutionState.Running) { kind = StartKind.Activate; } else if (kind == StartKind.Activate && e.PreviousExecutionState != ApplicationExecutionState.Running) { kind = StartKind.Launch; } // handle activate if (kind == StartKind.Activate) { CurrentState = BootstrapperStates.Activating; // never activate until launch has completed while (!CurrentStateHistory.ContainsValue(BootstrapperStates.Launched)) { await Task.Delay(10); } while (CurrentStateHistory.Count(x => x.Value == BootstrapperStates.Starting) != CurrentStateHistory.Count(x => x.Value == BootstrapperStates.Started)) { await Task.Delay(10); } CurrentState = BootstrapperStates.Starting; await OnStartAsync(kind, e); CurrentState = BootstrapperStates.Started; WindowLogic.ActivateWindow(ActivateWindowSources.Activating, SplashLogic); CurrentState = BootstrapperStates.Activated; } // handle first-time launch else if (kind == StartKind.Launch) { CurrentState = BootstrapperStates.Launching; SplashLogic.Show(e.SplashScreen, this); // do some one-time things SetupKeyboardListeners(); SetupLifecycleListeners(); SetupSystemListeners(); SetupCustomTitleBar(); // default Unspecified extended session if (AutoExtendExecutionSession) { await ExtendedSessionService.StartUnspecifiedAsync(); } CurrentState = BootstrapperStates.Initializing; // OnInitializeAsync await OnInitializeAsync(e); CurrentState = BootstrapperStates.Initialized; // if there no pre-existing root then generate root if (SplashLogic.Splashing || Window.Current.Content == null) { Window.Current.Content = CreateRootElement(e); } // okay, now handle launch bool restored = false; var IsPrelaunch = (e as LaunchActivatedEventArgs)?.PrelaunchActivated ?? false; switch (e.PreviousExecutionState) { case ApplicationExecutionState.Suspended: case ApplicationExecutionState.Terminated: OnResuming(this, null, IsPrelaunch ? AppExecutionState.Prelaunch : AppExecutionState.Terminated); var launchedEventArgs = e as ILaunchActivatedEventArgs; if (AutoRestoreAfterTerminated && DetermineStartCause(e) == AdditionalKinds.Primary || launchedEventArgs?.TileId == string.Empty) { CurrentState = BootstrapperStates.Restoring; restored = await NavigationService.LoadAsync(); CurrentState = BootstrapperStates.Restored; } break; } // handle if pre-launch (no UI) if (IsPrelaunch) { CurrentState = BootstrapperStates.Prelaunching; var runOnStartAsync = false; await OnPrelaunchAsync(e, out runOnStartAsync); CurrentState = BootstrapperStates.Prelaunched; if (!runOnStartAsync) { return; } } // handle if not restored (new launch) if (!restored) { CurrentState = BootstrapperStates.Starting; await OnStartAsync(StartKind.Launch, e); CurrentState = BootstrapperStates.Started; } // this will also hide any showing splashscreen WindowLogic.ActivateWindow(ActivateWindowSources.Launching, SplashLogic); CurrentState = BootstrapperStates.Launched; } }
private async void StartupOrchestratorAsync(IActivatedEventArgs e, StartKind kind) { DebugWrite($"kind:{kind} previous:{e.PreviousExecutionState}"); // check if this is the first activation at all, when we can save PreviousExecutionState and PrelaunchActivated if (!_firstActivationExecuted) { _firstActivationExecuted = true; PreviousExecutionState = e.PreviousExecutionState; PrelaunchActivated = (e as LaunchActivatedEventArgs)?.PrelaunchActivated ?? false; } // is the kind really right? we can figure it out from here if (kind == StartKind.Launch && CurrentStateHistory.ContainsValue(BootstrapperStates.Launching)) { kind = StartKind.Activate; } else if (kind == StartKind.Launch && e.PreviousExecutionState == ApplicationExecutionState.Running) { kind = StartKind.Activate; } else if (kind == StartKind.Activate && e.PreviousExecutionState != ApplicationExecutionState.Running) { kind = StartKind.Launch; } // handle activate if (kind == StartKind.Activate) { while (!CurrentStateHistory.ContainsValue(BootstrapperStates.Launched)) /* only activate after launch */ await { Task.Delay(10); } while (CurrentStateHistory.Count(x => x.Value == BootstrapperStates.Starting) != CurrentStateHistory.Count(x => x.Value == BootstrapperStates.Started)) { await Task.Delay(10); } await OperationWrapperAsync(BootstrapperStates.Starting, async() => await OnStartAsync(kind, e), BootstrapperStates.Starting); OperationWrapper(BootstrapperStates.Activating, () => { WindowLogic.ActivateWindow(ActivateWindowSources.Activating, SplashLogic); }, BootstrapperStates.Activated); } // handle first-time launch else if (kind == StartKind.Launch) { CurrentState = BootstrapperStates.Launching; SplashLogic.Show(e.SplashScreen, this); // do some one-time things SetupLifecycleListeners(); SetupBackListeners(); SetupCustomTitleBar(); // default Unspecified extended session if (AutoExtendExecutionSession) { await ExtendedSessionService.StartUnspecifiedAsync(); } await OperationWrapperAsync(BootstrapperStates.Initializing, async() => { await OnInitializeAsync(e); }, BootstrapperStates.Initialized); // if there no pre-existing root then generate root if (SplashLogic.Splashing || Window.Current.Content == null) { Window.Current.Content = CreateRootElement(e); } // okay, now handle launch var restored = false; var IsPrelaunch = (e as LaunchActivatedEventArgs)?.PrelaunchActivated ?? false; switch (e.PreviousExecutionState) { case ApplicationExecutionState.Suspended: case ApplicationExecutionState.Terminated: OnResuming(this, null, IsPrelaunch ? AppExecutionState.Prelaunch : AppExecutionState.Terminated); var launchedEventArgs = e as ILaunchActivatedEventArgs; if (AutoRestoreAfterTerminated && DetermineStartCause(e) == AdditionalKinds.Primary || launchedEventArgs?.TileId == string.Empty) { await OperationWrapperAsync(BootstrapperStates.Restoring, async() => { restored = await NavigationService.LoadAsync(); }, BootstrapperStates.Restored); } break; } // handle if pre-launch (no UI) if (IsPrelaunch) { var runOnStartAsync = false; await OperationWrapperAsync(BootstrapperStates.Prelaunching, async() => { await OnPrelaunchAsync(e, out runOnStartAsync); }, BootstrapperStates.Prelaunched); if (!runOnStartAsync) { return; } } // handle if not restored (new launch) if (!restored) { await OperationWrapperAsync(BootstrapperStates.Starting, async() => { await OnStartAsync(StartKind.Launch, e); }, BootstrapperStates.Started); } // this will also hide any showing splashscreen WindowLogic.ActivateWindow(ActivateWindowSources.Launching, SplashLogic); CurrentState = BootstrapperStates.Launched; } }