From a07279e7ba9760ef74aba0ac8f3557dc47c5bcc2 Mon Sep 17 00:00:00 2001 From: Andrew Szeto Date: Fri, 12 Jun 2026 20:52:45 -0700 Subject: [PATCH] fix(windows): handle missing registry key in isEnabled isEnabled() reads HKCU\...\CurrentVersion\Run through Registry.openPath, which throws a WindowsException when the key does not exist rather than returning null. On a fresh Windows install where no application has registered a startup entry, that key can be absent, so isEnabled() throws instead of reporting that auto-start is off. The exception propagates to callers and can abort application startup. This change guards the registry reads in isEnabled() and _isStartupApproved(). A missing Run key is treated as not enabled and a missing StartupApproved key as approved, so isEnabled() returns false on a fresh install instead of throwing. The catch is scoped to ERROR_FILE_NOT_FOUND and rethrows any other WindowsException (such as access denied) so genuine failures are not masked. This matches the macOS and Linux implementations, which return false when startup has not been configured. --- lib/src/app_auto_launcher_impl_windows.dart | 25 +++++++++++++++++++-- pubspec.yaml | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/src/app_auto_launcher_impl_windows.dart b/lib/src/app_auto_launcher_impl_windows.dart index a803fcb..8d5f691 100644 --- a/lib/src/app_auto_launcher_impl_windows.dart +++ b/lib/src/app_auto_launcher_impl_windows.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:launch_at_startup/src/app_auto_launcher.dart'; +import 'package:win32/win32.dart' + show ERROR_FILE_NOT_FOUND, HRESULT_FROM_WIN32, WindowsException; import 'package:win32_registry/win32_registry.dart' if (dart.library.html) 'noop.dart'; @@ -40,7 +42,17 @@ class AppAutoLauncherImplWindows extends AppAutoLauncher { @override Future isEnabled() async { - String? value = _regKey.getStringValue(appName); + final String? value; + try { + value = _regKey.getStringValue(appName); + } on WindowsException catch (e) { + // The Run key may not exist yet on a fresh Windows install where no + // application has registered for startup, which means auto-start is + // not enabled. Rethrow anything else (for example access denied) so a + // genuine failure is not silently masked. + if (e.hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) rethrow; + return false; + } return value == _registryValue && await _isStartupApproved(); } @@ -74,7 +86,16 @@ class AppAutoLauncherImplWindows extends AppAutoLauncher { // Odd first byte will prevent the app from autostarting // Empty or any other value will allow the app to autostart Future _isStartupApproved() async { - final value = _startupApprovedRegKey.getBinaryValue(appName); + final Uint8List? value; + try { + value = _startupApprovedRegKey.getBinaryValue(appName); + } on WindowsException catch (e) { + // The StartupApproved\Run key is created lazily and is often absent on + // a fresh install; a missing key is treated as approved by the null + // check below. Rethrow anything else so a genuine failure surfaces. + if (e.hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) rethrow; + value = null; + } if (value == null) { return true; diff --git a/pubspec.yaml b/pubspec.yaml index a7e9f36..4e2a1a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,7 @@ environment: dependencies: flutter: sdk: flutter + win32: ^5.8.0 win32_registry: ^2.0.0 dev_dependencies: