1- using System . Windows ;
1+ using System . Diagnostics ;
2+ using System . Windows ;
23using Microsoft . Extensions . DependencyInjection ;
34using Microsoft . Extensions . Logging ;
45using SecKey . App . Services ;
56using SecKey . App . ViewModels ;
7+ using SecKey . App . Views ;
68using SecKey . Core . Services ;
79using SecKey . Graph ;
810using SecKey . Graph . Auth ;
@@ -13,6 +15,8 @@ public partial class App : Application
1315{
1416 public IServiceProvider Services { get ; private set ; } = null ! ;
1517 public static new App Current => ( App ) Application . Current ;
18+ private SplashScreenWindow ? _splashScreen ;
19+ private readonly Stopwatch _startupStopwatch = Stopwatch . StartNew ( ) ;
1620
1721 private static void WriteCrashLog ( string source , Exception ? ex )
1822 {
@@ -51,84 +55,137 @@ protected override void OnStartup(StartupEventArgs e)
5155 a . SetObserved ( ) ;
5256 } ;
5357
54- try
58+ _splashScreen = new SplashScreenWindow ( ) ;
59+ MainWindow = _splashScreen ;
60+ _splashScreen . Show ( ) ;
61+ _splashScreen . Dispatcher . Invoke ( ( ) => { } , System . Windows . Threading . DispatcherPriority . Render ) ;
62+
63+ Dispatcher . BeginInvoke ( new Action ( async ( ) =>
5564 {
56- var services = new ServiceCollection ( ) ;
57- services . AddLogging ( b => b . AddDebug ( ) . SetMinimumLevel ( LogLevel . Information ) ) ;
65+ try
66+ {
67+ await InitializeApplicationAsync ( ) ;
68+ }
69+ catch ( Exception ex )
70+ {
71+ WriteCrashLog ( "Startup" , ex ) ;
72+ MessageBox . Show (
73+ $ "SecKey failed to start. Details were logged to %LocalAppData%\\ SecKey\\ crash.log.\n \n { ex } ",
74+ "Startup Error" ,
75+ MessageBoxButton . OK ,
76+ MessageBoxImage . Error ) ;
77+ Shutdown ( - 1 ) ;
78+ }
79+ } ) ) ;
80+ }
5881
59- // Default auth options; the Login page replaces the registered ITokenProvider with a configured one.
60- var defaultOptions = new AuthOptions
82+ private async Task InitializeApplicationAsync ( )
83+ {
84+ try
6185 {
62- Mode = AuthMode . Interactive ,
63- TenantId = "common" ,
64- Scopes = new [ ]
86+ _splashScreen ? . UpdateStatus ( "Preparing app services..." ) ;
87+
88+ var services = await Task . Run ( ( ) =>
6589 {
66- "https://graph.microsoft.com/Directory.ReadWrite.All" ,
67- "https://graph.microsoft.com/DeviceManagementApps.ReadWrite.All" ,
68- "https://graph.microsoft.com/DeviceManagementConfiguration.ReadWrite.All" ,
69- "https://graph.microsoft.com/DeviceManagementScripts.ReadWrite.All" ,
70- "https://graph.microsoft.com/DeviceManagementServiceConfig.ReadWrite.All" ,
71- "https://graph.microsoft.com/Group.ReadWrite.All" ,
72- "https://graph.microsoft.com/User.ReadWrite.All" ,
73- "https://graph.microsoft.com/Policy.ReadWrite.ConditionalAccess"
90+ var collection = new ServiceCollection ( ) ;
91+ collection . AddLogging ( b => b . AddDebug ( ) . SetMinimumLevel ( LogLevel . Information ) ) ;
92+
93+ // Default auth options; the Login page replaces the registered ITokenProvider with a configured one.
94+ var defaultOptions = new AuthOptions
95+ {
96+ Mode = AuthMode . Interactive ,
97+ TenantId = "common" ,
98+ Scopes = new [ ]
99+ {
100+ "https://graph.microsoft.com/Directory.ReadWrite.All" ,
101+ "https://graph.microsoft.com/DeviceManagementApps.ReadWrite.All" ,
102+ "https://graph.microsoft.com/DeviceManagementConfiguration.ReadWrite.All" ,
103+ "https://graph.microsoft.com/DeviceManagementScripts.ReadWrite.All" ,
104+ "https://graph.microsoft.com/DeviceManagementServiceConfig.ReadWrite.All" ,
105+ "https://graph.microsoft.com/Group.ReadWrite.All" ,
106+ "https://graph.microsoft.com/User.ReadWrite.All" ,
107+ "https://graph.microsoft.com/Policy.ReadWrite.ConditionalAccess"
108+ }
109+ } ;
110+
111+ collection . AddSecKeyAuth ( defaultOptions ) ;
112+ collection . AddSecKeyGraph ( ) ;
113+ collection . AddTransient < ISystemAuditService , SystemAuditService > ( ) ;
114+ collection . AddSingleton < INativeDeploymentSettingsService , NativeDeploymentSettingsService > ( ) ;
115+ collection . AddSingleton < AppSettingsExchangeService > ( ) ;
116+ collection . AddSingleton < AppUpdateService > ( ) ;
117+ collection . AddSingleton < BaselineContentBootstrapService > ( ) ;
118+
119+ collection . AddSingleton < EntraConfigService > ( _ => EntraConfigService . Instance ) ;
120+ collection . AddSingleton < AuthState > ( ) ;
121+ collection . AddSingleton < MainViewModel > ( ) ;
122+ collection . AddTransient < LoginViewModel > ( ) ;
123+ collection . AddTransient < DashboardViewModel > ( ) ;
124+ collection . AddTransient < IntuneAppsViewModel > ( ) ;
125+ collection . AddTransient < InfrastructureViewModel > ( ) ;
126+ collection . AddTransient < PoliciesViewModel > ( ) ;
127+ collection . AddTransient < GroupsViewModel > ( ) ;
128+ collection . AddTransient < ConditionalAccessViewModel > ( ) ;
129+ collection . AddTransient < UploadAppViewModel > ( ) ;
130+ collection . AddTransient < DeviceTaggingViewModel > ( ) ;
131+ collection . AddTransient < SecurityAnalyzerViewModel > ( ) ;
132+ collection . AddTransient < SystemHardeningViewModel > ( ) ;
133+ collection . AddTransient < RebootAnalyzerViewModel > ( ) ;
134+ collection . AddTransient < FileIntegrityViewModel > ( ) ;
135+ collection . AddTransient < IntuneBackupViewModel > ( ) ;
136+ collection . AddTransient < CertificateManagerViewModel > ( ) ;
137+ collection . AddTransient < SecureWipeViewModel > ( ) ;
138+ collection . AddTransient < NetworkTrafficViewModel > ( ) ;
139+ collection . AddTransient < HashScannerViewModel > ( ) ;
140+ collection . AddTransient < CredentialManagerViewModel > ( ) ;
141+ collection . AddTransient < EncryptedClipboardViewModel > ( ) ;
142+ collection . AddTransient < SshKeyManagerViewModel > ( ) ;
143+ collection . AddTransient < FileEncryptionToolViewModel > ( ) ;
144+ collection . AddTransient < SecurityVaultViewModel > ( ) ;
145+ collection . AddTransient < YaraScannerViewModel > ( ) ;
146+ collection . AddTransient < CveSearchViewModel > ( ) ;
147+ collection . AddTransient < ForensicsAnalyzerViewModel > ( ) ;
148+ collection . AddTransient < AdvancedForensicsViewModel > ( ) ;
149+ collection . AddTransient < GlobalSecureAccessViewModel > ( ) ;
150+ collection . AddTransient < WdacAppLockerViewModel > ( ) ;
151+ collection . AddTransient < SystemAuditViewModel > ( ) ;
152+ collection . AddTransient < PreferencesViewModel > ( ) ;
153+
154+ return collection . BuildServiceProvider ( ) ;
155+ } ) ;
156+
157+ Services = services ;
158+
159+ _splashScreen ? . UpdateStatus ( "Seeding baseline content..." ) ;
160+ try
161+ {
162+ await Task . Run ( ( ) => Services . GetRequiredService < BaselineContentBootstrapService > ( ) . EnsureBaselineContent ( ) ) ;
74163 }
75- } ;
76- services . AddSecKeyAuth ( defaultOptions ) ;
77- services . AddSecKeyGraph ( ) ;
78- services . AddTransient < ISystemAuditService , SystemAuditService > ( ) ;
79- services . AddSingleton < INativeDeploymentSettingsService , NativeDeploymentSettingsService > ( ) ;
80- services . AddSingleton < AppSettingsExchangeService > ( ) ;
81- services . AddSingleton < AppUpdateService > ( ) ;
82-
83- services . AddSingleton < EntraConfigService > ( _ => EntraConfigService . Instance ) ;
84- services . AddSingleton < AuthState > ( ) ;
85- services . AddSingleton < MainViewModel > ( ) ;
86- services . AddTransient < LoginViewModel > ( ) ;
87- services . AddTransient < DashboardViewModel > ( ) ;
88- services . AddTransient < IntuneAppsViewModel > ( ) ;
89- services . AddTransient < InfrastructureViewModel > ( ) ;
90- services . AddTransient < PoliciesViewModel > ( ) ;
91- services . AddTransient < GroupsViewModel > ( ) ;
92- services . AddTransient < ConditionalAccessViewModel > ( ) ;
93- services . AddTransient < UploadAppViewModel > ( ) ;
94- services . AddTransient < DeviceTaggingViewModel > ( ) ;
95- services . AddTransient < SecurityAnalyzerViewModel > ( ) ;
96- services . AddTransient < SystemHardeningViewModel > ( ) ;
97- services . AddTransient < RebootAnalyzerViewModel > ( ) ;
98- services . AddTransient < FileIntegrityViewModel > ( ) ;
99- services . AddTransient < IntuneBackupViewModel > ( ) ;
100- services . AddTransient < CertificateManagerViewModel > ( ) ;
101- services . AddTransient < SecureWipeViewModel > ( ) ;
102- services . AddTransient < NetworkTrafficViewModel > ( ) ;
103- services . AddTransient < HashScannerViewModel > ( ) ;
104- services . AddTransient < CredentialManagerViewModel > ( ) ;
105- services . AddTransient < EncryptedClipboardViewModel > ( ) ;
106- services . AddTransient < SshKeyManagerViewModel > ( ) ;
107- services . AddTransient < FileEncryptionToolViewModel > ( ) ;
108- services . AddTransient < SecurityVaultViewModel > ( ) ;
109- services . AddTransient < YaraScannerViewModel > ( ) ;
110- services . AddTransient < CveSearchViewModel > ( ) ;
111- services . AddTransient < ForensicsAnalyzerViewModel > ( ) ;
112- services . AddTransient < AdvancedForensicsViewModel > ( ) ;
113- services . AddTransient < GlobalSecureAccessViewModel > ( ) ;
114- services . AddTransient < WdacAppLockerViewModel > ( ) ;
115- services . AddTransient < SystemAuditViewModel > ( ) ;
116- services . AddTransient < PreferencesViewModel > ( ) ;
117-
118- Services = services . BuildServiceProvider ( ) ;
119-
120- var window = new MainWindow { DataContext = Services . GetRequiredService < MainViewModel > ( ) } ;
121- window . Show ( ) ;
164+ catch ( Exception bootstrapEx )
165+ {
166+ WriteCrashLog ( "BaselineContentBootstrap" , bootstrapEx ) ;
167+ }
168+
169+ _splashScreen ? . UpdateStatus ( "Loading workspace..." ) ;
170+ var minimumSplashTime = TimeSpan . FromSeconds ( 6 ) ;
171+ var remainingSplashTime = minimumSplashTime - _startupStopwatch . Elapsed ;
172+ if ( remainingSplashTime > TimeSpan . Zero )
173+ await Task . Delay ( remainingSplashTime ) ;
174+
175+ await Dispatcher . InvokeAsync ( ( ) =>
176+ {
177+ var window = new MainWindow { DataContext = Services . GetRequiredService < MainViewModel > ( ) } ;
178+ MainWindow = window ;
179+ window . Show ( ) ;
180+ _splashScreen ? . Close ( ) ;
181+ _splashScreen = null ;
182+ } ) ;
122183 }
123- catch ( Exception ex )
184+ catch
124185 {
125- WriteCrashLog ( "Startup" , ex ) ;
126- MessageBox . Show (
127- $ "SecKey failed to start. Details were logged to %LocalAppData%\\ SecKey\\ crash.log.\n \n { ex } ",
128- "Startup Error" ,
129- MessageBoxButton . OK ,
130- MessageBoxImage . Error ) ;
131- Shutdown ( - 1 ) ;
186+ _splashScreen ? . Close ( ) ;
187+ _splashScreen = null ;
188+ throw ;
132189 }
133190 }
134191}
0 commit comments