diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b4b3e9f1..6f844578c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## Unreleased +### Fixes + +- Don't add WinUI exception integration on mobile platforms ([#2821](https://github.com/getsentry/sentry-dotnet/pull/2821)) + +### API breaking Changes + +#### Removed APIs + +- A number of `[Obsolete]` options have been removed ([#2841](https://github.com/getsentry/sentry-dotnet/pull/2841)) + - `BeforeSend` - use `SetBeforeSend` instead. + - `BeforeSendTransaction` - use `SetBeforeSendTransaction` instead. + - `BeforeBreadcrumb` - use `SetBeforeBreadcrumb` instead. + - `CreateHttpClientHandler` - use `CreateHttpMessageHandler` instead. + - `ReportAssemblies` - use `ReportAssembliesMode` instead. + - `KeepAggregateException` - This property is no longer used and has no replacement. + - `DisableTaskUnobservedTaskExceptionCapture` method has been renamed to `DisableUnobservedTaskExceptionCapture`. + +#### Changed APIs + +- `DebugImage` and `DebugMeta` moved to `Sentry.Protocol` namespace. ([#2815](https://github.com/getsentry/sentry-dotnet/pull/2815)) +- `SentryClient.Dispose` is no longer obsolete ([#2842](https://github.com/getsentry/sentry-dotnet/pull/2842)) + ## 4.0.0-alpha.0 This release brings support for .NET 8 Native AOT publishing and cleans up some of the old APIs that have outlived their use. @@ -43,14 +65,6 @@ Additionally, we're dropping support for some of the old target frameworks, plea - Obsolete setter `Sentry.PlatformAbstractions.Runtime.Identifier` has been removed ([2764](https://github.com/getsentry/sentry-dotnet/pull/2764)) - `Sentry.Values` is now internal as it is never exposed in the public API ([#2771](https://github.com/getsentry/sentry-dotnet/pull/2771)) - `TracePropagationTarget` class has been removed, use the `SubstringOrRegexPattern` class instead. ([#2763](https://github.com/getsentry/sentry-dotnet/pull/2763)) -- A number of `[Obsolete]` options have been removed ([#2841](https://github.com/getsentry/sentry-dotnet/pull/2841)) - - `BeforeSend` - use `SetBeforeSend` instead. - - `BeforeSendTransaction` - use `SetBeforeSendTransaction` instead. - - `BeforeBreadcrumb` - use `SetBeforeBreadcrumb` instead. - - `CreateHttpClientHandler` - use `CreateHttpMessageHandler` instead. - - `ReportAssemblies` - use `ReportAssembliesMode` instead. - - `KeepAggregateException` - This property is no longer used and has no replacement. - - `DisableTaskUnobservedTaskExceptionCapture` method has been renamed to `DisableUnobservedTaskExceptionCapture`. #### Changed APIs @@ -87,20 +101,22 @@ Additionally, we're dropping support for some of the old target frameworks, plea - `DebugImage.ImageAddress` changed to `long?`. ([#2725](https://github.com/getsentry/sentry-dotnet/pull/2725)) - Contexts now inherits from `IDictionary` rather than `ConcurrentDictionary`. The specific dictionary being used is an implementation detail. ([#2729](https://github.com/getsentry/sentry-dotnet/pull/2729)) - Transaction names for ASP.NET Core are now consistently named `HTTP-VERB /path` (e.g. `GET /home`). Previously the leading forward slash was missing for some endpoints. ([#2808](https://github.com/getsentry/sentry-dotnet/pull/2808)) -- `DebugImage` and `DebugMeta` moved to `Sentry.Protocol` namespace. ([#2815](https://github.com/getsentry/sentry-dotnet/pull/2815)) -- `SentryClient.Dispose` is no longer obsolete ([#2842](https://github.com/getsentry/sentry-dotnet/pull/2842)) - -### Fixes - -- Don't add WinUI exception integration on mobile platforms ([#2821](https://github.com/getsentry/sentry-dotnet/pull/2821)) ### Features #### Native AOT -Native AOT publishing for compilation support for .NET 7+ has been added to Sentry, Sentry.Serilog, Sentry.Profiling, Sentry.OpenTelemetry and Sentry.NLog. There are some functional differences when publishing Native AOT: +Native AOT publishing support for .NET 8 has been added to Sentry for the following platforms: + +- Windows +- Linux +- macOS +- Mac Catalyst +- iOS + +There are some functional differences when publishing Native AOT: -- `StackTraceMode.Enhanced` is ignored because it's not available when publishing Native AOT. The mechanism to generate these ehanced stack traces relies heavily on reflection which isn't compatible with trimming. +- `StackTraceMode.Enhanced` is ignored because it's not available when publishing Native AOT. The mechanism to generate these enhanced stack traces relies heavily on reflection which isn't compatible with trimming. - Reflection cannot be leveraged for JSON Serialization and you may need to use `SentryOptions.AddJsonSerializerContext` to supply a serialization context for types that you'd like to send to Sentry (e.g. in the `Span.Context`). ([#2732](https://github.com/getsentry/sentry-dotnet/pull/2732), [#2793](https://github.com/getsentry/sentry-dotnet/pull/2793)) - WinUI applications: when publishing Native AOT, Sentry isn't able to automatically register an unhandled exception handler because that relies on reflection. You'll need to [register the unhandled event handler manually](https://github.com/getsentry/sentry-dotnet/issues/2778) instead. diff --git a/integration-test/common.ps1 b/integration-test/common.ps1 index e16346df6f..cf63fdbbbc 100644 --- a/integration-test/common.ps1 +++ b/integration-test/common.ps1 @@ -70,7 +70,7 @@ BeforeAll { if (-not (Test-Path env:CI)) { Write-Host "Packaging $name, expected output path: $packagePath" - dotnet pack "$PSScriptRoot/../src/$name" -c Release --nologo --no-restore -p:Version=$packageVersion -p:IsPackable=true | ForEach-Object { Write-Host $_ } + dotnet pack "$PSScriptRoot/../src/$name" -c Release --nologo -p:Version=$packageVersion -p:IsPackable=true | ForEach-Object { Write-Host $_ } if ($LASTEXITCODE -ne 0) { throw "Failed to package $name." @@ -161,7 +161,7 @@ BeforeAll { } $packageVersion = GetSentryPackageVersion - dotnet add package $package --source $PSScriptRoot/packages --version $packageVersion | ForEach-Object { Write-Host $_ } + dotnet add package $package --source $PSScriptRoot/packages --version $packageVersion --no-restore | ForEach-Object { Write-Host $_ } if ($LASTEXITCODE -ne 0) { throw "Failed to add package dependency to the test app project." diff --git a/integration-test/net4-console/Program.cs b/integration-test/net4-console/Program.cs new file mode 100644 index 0000000000..3d0664eb99 --- /dev/null +++ b/integration-test/net4-console/Program.cs @@ -0,0 +1,22 @@ +using Sentry; +using Sentry.Extensibility; +using Sentry.Protocol.Envelopes; + +// Initialize the Sentry SDK. (It is not necessary to dispose it.) +SentrySdk.Init(options => +{ + options.Dsn = "http://key@127.0.0.1:9999/123"; + options.Debug = true; + options.Transport = new FakeTransport(); +}); + +throw new ApplicationException("Something happened!"); + +internal class FakeTransport : ITransport +{ + public virtual Task SendEnvelopeAsync(Envelope envelope, CancellationToken cancellationToken = default) + { + envelope.Serialize(Console.OpenStandardOutput(), null); + return Task.CompletedTask; + } +} diff --git a/integration-test/net4-console/console-app.csproj b/integration-test/net4-console/console-app.csproj new file mode 100644 index 0000000000..a6c56df241 --- /dev/null +++ b/integration-test/net4-console/console-app.csproj @@ -0,0 +1,12 @@ + + + + Exe + net462 + console_app + enable + 10.0 + true + + + diff --git a/integration-test/runtime.Tests.ps1 b/integration-test/runtime.Tests.ps1 index 4fefa440b5..bdd79d0ed4 100644 --- a/integration-test/runtime.Tests.ps1 +++ b/integration-test/runtime.Tests.ps1 @@ -3,7 +3,7 @@ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' . $PSScriptRoot/common.ps1 -Describe 'Console app ()' -ForEach @( +Describe 'Console app NativeAOT ()' -ForEach @( @{ framework = "net8.0" } ) { BeforeAll { @@ -102,3 +102,37 @@ internal class FakeTransport : ITransport runConsoleApp $false | Should -AnyElementMatch 'This looks like a standard JIT/AOT application build.' } } + +# This ensures we don't have a regression for https://github.com/getsentry/sentry-dotnet/issues/2825 +Describe 'Console app regression (missing System.Reflection.Metadata)' { + AfterAll { + dotnet remove ./net4-console/console-app.csproj package Sentry + } + + It "Ensure System.Reflection.Metadata is not missing" { + $path = './net4-console' + Remove-Item -Recurse -Force -Path @("$path/bin", "$path/obj") -ErrorAction SilentlyContinue + AddPackageReference $path 'Sentry' + + function runConsoleApp() + { + $executable = { dotnet run --project $path -c Release } + Write-Host "::group::Executing $executable" + try + { + $executable.Invoke() | ForEach-Object { + Write-Host " $_" + $_ + } + } + finally + { + Write-Host "::endgroup::" + } + } + + $output = runConsoleApp + $output | Should -Not -AnyElementMatch 'Could not load file or assembly.' + $output | Should -AnyElementMatch '"exception":{"values":\[{"type":"System.ApplicationException","value":"Something happened!"' + } +} diff --git a/samples/Sentry.Samples.Console.Basic/Sentry.Samples.Console.Basic.csproj b/samples/Sentry.Samples.Console.Basic/Sentry.Samples.Console.Basic.csproj index 3930e6a11c..96b998db7c 100644 --- a/samples/Sentry.Samples.Console.Basic/Sentry.Samples.Console.Basic.csproj +++ b/samples/Sentry.Samples.Console.Basic/Sentry.Samples.Console.Basic.csproj @@ -4,8 +4,8 @@ Exe enable enable - net8.0 - true + net8.0;net6.0;netstandard2.1;netstandard2.0;net462 + true diff --git a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj index 743a545c71..8126655549 100644 --- a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj +++ b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj @@ -7,6 +7,7 @@ true 11.0 true + true - - $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) - - - iossimulator-arm64 - - diff --git a/samples/Sentry.Samples.Maui/MauiProgram.cs b/samples/Sentry.Samples.Maui/MauiProgram.cs index dc8d479fe3..119984b80e 100644 --- a/samples/Sentry.Samples.Maui/MauiProgram.cs +++ b/samples/Sentry.Samples.Maui/MauiProgram.cs @@ -16,6 +16,8 @@ public static MauiApp CreateMauiApp() // By default, we will send the last 100 breadcrumbs with each event. // If you want to see everything we can capture from MAUI, you may wish to use a larger value. options.MaxBreadcrumbs = 1000; + + options.Debug = true; }) .ConfigureFonts(fonts => diff --git a/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj b/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj index 1c765a1852..ab002ae9bd 100644 --- a/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj +++ b/samples/Sentry.Samples.Maui/Sentry.Samples.Maui.csproj @@ -16,6 +16,7 @@ true enable false + true Sentry.Samples.Maui @@ -58,11 +59,12 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) android-arm64 - iossimulator-arm64 + ios-arm64 + iossimulator-arm64 maccatalyst-arm64 android-x64 - iossimulator-x64 + iossimulator-x64 maccatalyst-x64 diff --git a/src/Sentry.AspNetCore/Sentry.AspNetCore.csproj b/src/Sentry.AspNetCore/Sentry.AspNetCore.csproj index 5188dcf12a..b792f3d350 100644 --- a/src/Sentry.AspNetCore/Sentry.AspNetCore.csproj +++ b/src/Sentry.AspNetCore/Sentry.AspNetCore.csproj @@ -1,7 +1,7 @@  - net6.0;netstandard2.0 + net8.0;net6.0;netstandard2.0 $(PackageTags);AspNetCore;MVC Official ASP.NET Core integration for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. diff --git a/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs b/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs index 62bb8ac30f..4be7cbf8d5 100644 --- a/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs @@ -29,10 +29,14 @@ public async Task InvokeAsync(HttpContext context, RequestDelegate next) var request = context.Request; if (request.Method == "OPTIONS") { - headers.Add("Access-Control-Allow-Origin", new[] { (string)request.Headers["Origin"]! }); - headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" }); - headers.Add("Access-Control-Allow-Methods", new[] { "POST, OPTIONS" }); - headers.Add("Access-Control-Allow-Credentials", new[] { "true" }); + if (request.Headers.TryGetValue("Origin", out var origin) && !string.IsNullOrEmpty(origin)) + { + headers.Append("Access-Control-Allow-Origin", (string)origin!); + } + + headers.Append("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); + headers.Append("Access-Control-Allow-Methods", "POST, OPTIONS"); + headers.Append("Access-Control-Allow-Credentials", "true"); response.StatusCode = 200; return; } diff --git a/src/Sentry.Azure.Functions.Worker/Sentry.Azure.Functions.Worker.csproj b/src/Sentry.Azure.Functions.Worker/Sentry.Azure.Functions.Worker.csproj index 96ba7b4cc4..6d2be7ab2b 100644 --- a/src/Sentry.Azure.Functions.Worker/Sentry.Azure.Functions.Worker.csproj +++ b/src/Sentry.Azure.Functions.Worker/Sentry.Azure.Functions.Worker.csproj @@ -1,7 +1,7 @@ - net6.0;netstandard2.0 + net8.0;net6.0;netstandard2.0 $(PackageTags);Azure;Functions;Worker Official Azure Functions Worker SDK integration for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. diff --git a/src/Sentry.NLog/Sentry.NLog.csproj b/src/Sentry.NLog/Sentry.NLog.csproj index c81d5bd233..b0dc9f8049 100644 --- a/src/Sentry.NLog/Sentry.NLog.csproj +++ b/src/Sentry.NLog/Sentry.NLog.csproj @@ -1,7 +1,7 @@  - net6.0;netstandard2.0;net462 + net8.0;net6.0;netstandard2.1;netstandard2.0;net462 $(PackageTags);Logging;NLog Official NLog integration for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. true diff --git a/src/Sentry.OpenTelemetry/Sentry.OpenTelemetry.csproj b/src/Sentry.OpenTelemetry/Sentry.OpenTelemetry.csproj index e8d81f6ed8..d1cf046c1d 100644 --- a/src/Sentry.OpenTelemetry/Sentry.OpenTelemetry.csproj +++ b/src/Sentry.OpenTelemetry/Sentry.OpenTelemetry.csproj @@ -3,7 +3,7 @@ Official OpenTelemetry integration for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. $(PackageTags);OpenTelemetry - net6.0;netstandard2.1;netstandard2.0;net462 + net8.0;net6.0;netstandard2.1;netstandard2.0;net462 enable diff --git a/src/Sentry.Serilog/Sentry.Serilog.csproj b/src/Sentry.Serilog/Sentry.Serilog.csproj index 7abb79e979..4e2b63e861 100644 --- a/src/Sentry.Serilog/Sentry.Serilog.csproj +++ b/src/Sentry.Serilog/Sentry.Serilog.csproj @@ -1,7 +1,7 @@  - net6.0;netstandard2.1;netstandard2.0;net462 + net8.0;net6.0;netstandard2.1;netstandard2.0;net462 $(PackageTags);Logging;Serilog Official Serilog integration for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. true diff --git a/src/Sentry/Internal/DebugStackTrace.cs b/src/Sentry/Internal/DebugStackTrace.cs index 1b9bc55709..f2c150248b 100644 --- a/src/Sentry/Internal/DebugStackTrace.cs +++ b/src/Sentry/Internal/DebugStackTrace.cs @@ -1,6 +1,5 @@ using Sentry.Internal.Extensions; using Sentry.Extensibility; -using Sentry.Native; using Sentry.Internal.ILSpy; using Sentry.Protocol; @@ -17,8 +16,11 @@ internal class DebugStackTrace : SentryStackTrace private readonly Dictionary _debugImageIndexByModule = new(); private const int DebugImageMissing = -1; private bool _debugImagesMerged; + +#if NET6_0_OR_GREATER private Dictionary? _nativeDebugImages; private HashSet _usedNativeDebugImages = new(); +#endif /* * NOTE: While we could improve these regexes, doing so might break exception grouping on the backend. @@ -220,6 +222,7 @@ private IEnumerable CreateFrames(StackTrace stackTrace, bool i } } +#if NET6_0_OR_GREATER /// /// Native AOT implementation of CreateFrame. /// Native frames have only limited method information at runtime (and even that can be disabled). @@ -237,7 +240,15 @@ private IEnumerable CreateFrames(StackTrace stackTrace, bool i frame.ImageAddress = imageAddress; frame.InstructionAddress = stackFrame.GetNativeIP(); - _nativeDebugImages ??= C.LoadDebugImages(_options.DiagnosticLogger); +#if __ANDROID__ + // TODO there will be support for NativeAOT in the future. + _nativeDebugImages ??= new(); +#elif __IOS__ || MACCATALYST + _nativeDebugImages ??= Sentry.iOS.C.LoadDebugImages(_options.DiagnosticLogger); +#else + _nativeDebugImages ??= Sentry.Native.C.LoadDebugImages(_options.DiagnosticLogger); +#endif + if (!_usedNativeDebugImages.Contains(imageAddress) && _nativeDebugImages.TryGetValue(imageAddress, out var debugImage)) { _usedNativeDebugImages.Add(imageAddress); @@ -261,6 +272,7 @@ internal static SentryStackFrame ParseNativeAOTToString(string info) } return frame; } +#endif /// /// Default the implementation of CreateFrame. @@ -352,7 +364,9 @@ internal static SentryStackFrame ParseNativeAOTToString(string info) internal SentryStackFrame? CreateFrame(IStackFrame stackFrame) { var frame = TryCreateManagedFrame(stackFrame); +#if NET6_0_OR_GREATER frame ??= TryCreateNativeAOTFrame(stackFrame); +#endif if (frame is null) { return null; diff --git a/src/Sentry/Internal/Enricher.cs b/src/Sentry/Internal/Enricher.cs index 2b24da4990..e7acaf0a55 100644 --- a/src/Sentry/Internal/Enricher.cs +++ b/src/Sentry/Internal/Enricher.cs @@ -36,7 +36,16 @@ public void Apply(IEventLike eventLike) // RuntimeInformation.OSDescription is throwing on Mono 5.12 if (!PlatformAbstractions.Runtime.Current.IsMono()) { +#if NETFRAMEWORK + // RuntimeInformation.* throws on .NET Framework on macOS/Linux + try { + eventLike.Contexts.OperatingSystem.RawDescription = RuntimeInformation.OSDescription; + } catch { + eventLike.Contexts.OperatingSystem.RawDescription = Environment.OSVersion.VersionString; + } +#else eventLike.Contexts.OperatingSystem.RawDescription = RuntimeInformation.OSDescription; +#endif } } diff --git a/src/Sentry/Platforms/iOS/CFunctions.cs b/src/Sentry/Platforms/iOS/CFunctions.cs new file mode 100644 index 0000000000..3463b3f7fa --- /dev/null +++ b/src/Sentry/Platforms/iOS/CFunctions.cs @@ -0,0 +1,38 @@ +using Sentry.Extensibility; +using Sentry.Internal.Extensions; +using Sentry.Protocol; + +namespace Sentry.iOS; + +internal static class C +{ + internal static Dictionary LoadDebugImages(IDiagnosticLogger? logger) + { + logger?.LogDebug("Collecting a list of native debug images."); + var result = new Dictionary(); + try + { + var cList = SentryCocoaHybridSdk.DebugImages; + logger?.LogDebug("There are {0} native debug images, parsing the information.", cList.Length); + foreach (var cItem in cList) + { + if (cItem.ImageAddress?.ParseHexAsLong() is { } imageAddress) + { + result.Add(imageAddress, new DebugImage() + { + CodeFile = cItem.CodeFile, + ImageAddress = imageAddress, + ImageSize = cItem.ImageSize?.LongValue, + DebugId = cItem.DebugID, + Type = cItem.Type, + }); + } + } + } + catch (Exception e) + { + logger?.LogWarning("Error loading the list of debug images", e); + } + return result; + } +} diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 167a944d91..5ce21eda74 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -21,34 +21,28 @@ - + true - - - %(RecursiveDir)\%(Filename)%(Extension) - - - - - - $(BenDemystifierLink) - - - - - - - - - + + + + %(RecursiveDir)\%(Filename)%(Extension) + + + + + + + diff --git a/src/Sentry/buildTransitive/Sentry.targets b/src/Sentry/buildTransitive/Sentry.targets index 27f144d690..4384e64f48 100644 --- a/src/Sentry/buildTransitive/Sentry.targets +++ b/src/Sentry/buildTransitive/Sentry.targets @@ -128,7 +128,12 @@ - + true $(PublishDir) diff --git a/test/Sentry.Tests/Internals/DebugStackTraceTests.verify.cs b/test/Sentry.Tests/Internals/DebugStackTraceTests.verify.cs index 45753fc04a..556d1590c7 100644 --- a/test/Sentry.Tests/Internals/DebugStackTraceTests.verify.cs +++ b/test/Sentry.Tests/Internals/DebugStackTraceTests.verify.cs @@ -192,6 +192,7 @@ void CheckStackTraceIsUnchanged(SentryStackTrace stackTrace) } } +#if NET6_0_OR_GREATER [Fact] public void ParseNativeAOTToString() { @@ -214,8 +215,8 @@ public void ParseNativeAOTToString() Assert.Null(frame.Package); } -// TODO: Create integration test to test this behaviour when publishing AOT apps -// See https://github.com/getsentry/sentry-dotnet/issues/2772 + // TODO: Create integration test to test this behaviour when publishing AOT apps + // See https://github.com/getsentry/sentry-dotnet/issues/2772 [Fact] public Task CreateFrame_ForNativeAOT() { @@ -230,6 +231,7 @@ public Task CreateFrame_ForNativeAOT() return VerifyJson(frame.ToJsonString()); } +#endif private class InjectableDebugStackTrace : DebugStackTrace { diff --git a/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs b/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs index ba16e33818..39e65a26af 100644 --- a/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs +++ b/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs @@ -231,6 +231,7 @@ public void ConfigureAppFrame_NativeAOTWithoutMethodInfo_InAppIsNull() Assert.Null(sut.InApp); } +#if NET6_0_OR_GREATER [Fact] public void ConfigureAppFrame_NativeAOTWithoutMethodInfo_InAppIsSet() { @@ -244,5 +245,5 @@ public void ConfigureAppFrame_NativeAOTWithoutMethodInfo_InAppIsSet() sut.ConfigureAppFrame(new()); Assert.True(sut.InApp); } - +#endif }