From 83e2f9b35b7f5d9311ec614c579ea51f8c727af4 Mon Sep 17 00:00:00 2001 From: Todd Anderson Date: Tue, 26 May 2026 10:16:01 -0400 Subject: [PATCH] fix: gracefully handle MAUI unavailability in non-MAUI Windows apps PlatformConnectivity, AppInfo, and DeviceInfo all call MAUI APIs that require platform initialization. In WPF/WinForms apps targeting net8.0-windows, MAUI is never initialized, causing a TypeInitializationException during LdClient.Init(). Guard the static constructor with a _mauiAvailable flag and fall back to safe defaults (assume connected, return null for app/device info) when MAUI is not available at runtime. --- .../src/PlatformSpecific/AppInfo.maui.cs | 20 +++++++--- .../src/PlatformSpecific/Connectivity.maui.cs | 20 ++++++++-- .../src/PlatformSpecific/DeviceInfo.maui.cs | 40 ++++++++++++++----- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/pkgs/sdk/client/src/PlatformSpecific/AppInfo.maui.cs b/pkgs/sdk/client/src/PlatformSpecific/AppInfo.maui.cs index 8c938e32..cd33f2dd 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/AppInfo.maui.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/AppInfo.maui.cs @@ -5,10 +5,20 @@ namespace LaunchDarkly.Sdk.Client.PlatformSpecific { internal static partial class AppInfo { - internal static ApplicationInfo? GetAppInfo() => new ApplicationInfo( - Microsoft.Maui.ApplicationModel.AppInfo.Current.PackageName, - Microsoft.Maui.ApplicationModel.AppInfo.Current.Name, - Microsoft.Maui.ApplicationModel.AppInfo.Current.BuildString, - Microsoft.Maui.ApplicationModel.AppInfo.Current.VersionString); + internal static ApplicationInfo? GetAppInfo() + { + try + { + return new ApplicationInfo( + Microsoft.Maui.ApplicationModel.AppInfo.Current.PackageName, + Microsoft.Maui.ApplicationModel.AppInfo.Current.Name, + Microsoft.Maui.ApplicationModel.AppInfo.Current.BuildString, + Microsoft.Maui.ApplicationModel.AppInfo.Current.VersionString); + } + catch + { + return null; + } + } } } diff --git a/pkgs/sdk/client/src/PlatformSpecific/Connectivity.maui.cs b/pkgs/sdk/client/src/PlatformSpecific/Connectivity.maui.cs index ef8acdde..9eeb7cb2 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/Connectivity.maui.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/Connectivity.maui.cs @@ -7,20 +7,34 @@ namespace LaunchDarkly.Sdk.Client.PlatformSpecific { internal static partial class PlatformConnectivity { + private static readonly bool _mauiAvailable; + static PlatformConnectivity() { - Connectivity.Current.ConnectivityChanged += (sender, args) => ConnectivityChanged?.Invoke(sender, EventArgs.Empty); + try + { + Connectivity.Current.ConnectivityChanged += (sender, args) => ConnectivityChanged?.Invoke(sender, EventArgs.Empty); + _mauiAvailable = true; + } + catch + { + _mauiAvailable = false; + } } /// /// Gets the current state of network access. /// - public static LdNetworkAccess LdNetworkAccess => Convert(Connectivity.Current.NetworkAccess); + public static LdNetworkAccess LdNetworkAccess => + _mauiAvailable ? Convert(Connectivity.Current.NetworkAccess) : LdNetworkAccess.Internet; /// /// Gets the active connectivity types for the device. /// - public static IEnumerable LdConnectionProfiles => Connectivity.Current.ConnectionProfiles.Distinct().Select(Convert); + public static IEnumerable LdConnectionProfiles => + _mauiAvailable + ? Connectivity.Current.ConnectionProfiles.Distinct().Select(Convert) + : Enumerable.Empty(); /// /// Occurs when network access or profile has changed. This is just a signal and the diff --git a/pkgs/sdk/client/src/PlatformSpecific/DeviceInfo.maui.cs b/pkgs/sdk/client/src/PlatformSpecific/DeviceInfo.maui.cs index f15e5363..37fb1dd5 100644 --- a/pkgs/sdk/client/src/PlatformSpecific/DeviceInfo.maui.cs +++ b/pkgs/sdk/client/src/PlatformSpecific/DeviceInfo.maui.cs @@ -5,18 +5,36 @@ namespace LaunchDarkly.Sdk.Client.PlatformSpecific { internal static partial class DeviceInfo { - internal static OsInfo? GetOsInfo() => - new OsInfo( - PlatformToFamilyString(Devices.DeviceInfo.Current.Platform), - Devices.DeviceInfo.Current.Platform.ToString(), - Devices.DeviceInfo.Current.VersionString - ); + internal static OsInfo? GetOsInfo() + { + try + { + return new OsInfo( + PlatformToFamilyString(Devices.DeviceInfo.Current.Platform), + Devices.DeviceInfo.Current.Platform.ToString(), + Devices.DeviceInfo.Current.VersionString + ); + } + catch + { + return null; + } + } - internal static LaunchDarkly.Sdk.EnvReporting.LayerModels.DeviceInfo? GetDeviceInfo() => - new EnvReporting.LayerModels.DeviceInfo( - Devices.DeviceInfo.Current.Manufacturer, - Devices.DeviceInfo.Current.Model - ); + internal static LaunchDarkly.Sdk.EnvReporting.LayerModels.DeviceInfo? GetDeviceInfo() + { + try + { + return new EnvReporting.LayerModels.DeviceInfo( + Devices.DeviceInfo.Current.Manufacturer, + Devices.DeviceInfo.Current.Model + ); + } + catch + { + return null; + } + } private static string PlatformToFamilyString(Devices.DevicePlatform platform) { if (platform == Devices.DevicePlatform.Android)