Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable .NET 8 for uwp MultiTarget, upgrade packages #618

Merged
merged 39 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8766f32
Fix possible nullrefs
Arlodotexe Aug 6, 2024
5b14120
Only reference WindowsDesktop SDK on legacy uwp
Arlodotexe Aug 6, 2024
b7df046
Updating tooling
Arlodotexe Aug 6, 2024
694177d
Include CommunityToolkit.AppServices.targets in nupkg for net8.0-wind…
Arlodotexe Aug 6, 2024
09617b2
Update tooling to latest main
Arlodotexe Aug 23, 2024
f05e004
Merge branch 'main' into uwp-net8-windows
Arlodotexe Aug 23, 2024
e2929f3
Add support for modern .NET to AppServices library
Sergio0694 Oct 11, 2024
d423cfe
Update components/AppServices/src/MultiTarget.props
Arlodotexe Oct 14, 2024
c9ed532
Merge pull request #576 from CommunityToolkit/user/sergiopedri/uwp-ne…
Arlodotexe Oct 14, 2024
eaf038c
Merge branch 'main' into uwp-net8-windows
Arlodotexe Oct 14, 2024
49de309
Fixed invalid namespace reference
Arlodotexe Oct 14, 2024
7c88625
Update Microsoft.Windows.SDK.Contracts to only be included under nets…
Arlodotexe Oct 14, 2024
bcd3874
Update Microsoft.Windows.SDK.Contracts to 10.0.26100.1742
Arlodotexe Oct 14, 2024
cdbde34
Fix name of AppService targets
Sergio0694 Oct 15, 2024
ebb7d3e
Merge pull request #578 from CommunityToolkit/user/sergiopedri/fix-ap…
Arlodotexe Oct 15, 2024
f38e397
Merge branch 'main' into uwp-net8-windows
Arlodotexe Oct 31, 2024
1a9bbf8
Fixed AoT build error
Arlodotexe Nov 13, 2024
8ce50b7
Update subproject commit reference in tooling
Arlodotexe Nov 13, 2024
ce173c4
Update .NET version to 9.0 and related dependencies
Arlodotexe Dec 4, 2024
1f3d7b4
Merge branch 'main' into uwp-net8-windows
Arlodotexe Dec 13, 2024
bb8ccef
Add workaround for WebView2 SDKReference issue in Directory.Build.tar…
Arlodotexe Dec 19, 2024
148f004
Update CommunityToolkit package references to PR version 8.2.241219-p…
Arlodotexe Dec 19, 2024
c95c9b0
Update subproject commit reference in tooling
Arlodotexe Dec 19, 2024
3bd4e8a
Update TFM overrides
Arlodotexe Dec 20, 2024
7717f6f
Minor cleanup, remove templated example
Arlodotexe Dec 20, 2024
348a368
Updated away from deprecated Behaviors namespaces
Arlodotexe Dec 20, 2024
3870435
Add 'net9.0-windows10.0.17763.0' TFM for UWP
Sergio0694 Dec 21, 2024
14b9a8e
Ran XAML styler
Arlodotexe Dec 23, 2024
91de16d
Use normal windows-latest runner for Xaml Style Check
Arlodotexe Dec 23, 2024
9e161f1
Use tooling to declare GlobalUsings
Arlodotexe Dec 23, 2024
5c0fb58
Fix some trim warnings
Sergio0694 Dec 23, 2024
b2c0ab9
Update CommunityToolkit package references to version 8.2.241223-buil…
Arlodotexe Dec 24, 2024
d96cd92
Update tooling pointer to PR https://github.com/CommunityToolkit/Tool…
Arlodotexe Dec 24, 2024
db70025
Add trim annotations to 'TokenView'
Sergio0694 Dec 24, 2024
1227d43
Just suppress the trim warning for now
Sergio0694 Dec 24, 2024
f66a707
Update tooling pointer to PR https://github.com/CommunityToolkit/Tool…
Sergio0694 Dec 25, 2024
ba37852
Disable WUX in 'Notifications' package
Sergio0694 Dec 25, 2024
d6c144b
Update tooling pointer to commit b121eb57cc0fdca03206a9e1a08960d7e3cd…
Sergio0694 Dec 25, 2024
d2d708b
Switch to file-scoped namespaces
Sergio0694 Dec 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.208.0/containers/dotnet/.devcontainer/base.Dockerfile

# [Choice] .NET version: 6.0, 5.0, 3.1, 6.0-bullseye, 5.0-bullseye, 3.1-bullseye, 6.0-focal, 5.0-focal, 3.1-focal, etc
ARG VARIANT="8.0-bullseye-slim"
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT}
# See https://github.com/devcontainers/images/tree/main/src/dotnet for image choices
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:9.0

# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"args": {
// Update 'VARIANT' to pick a .NET Core version: 3.1, 5.0, 6.0
// Append -bullseye or -focal to pin to an OS version.
"VARIANT": "6.0",
"VARIANT": "9.0",
// Options
"NODE_VERSION": "lts/*"
}
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ on:
merge_group:

env:
DOTNET_VERSION: ${{ '8.0.201' }}
DOTNET_INSTALL_DIR: dotnet-install
DOTNET_ROOT: dotnet-install
DOTNET_VERSION: ${{ '9.0.x' }}
ENABLE_DIAGNOSTICS: false
#COREHOST_TRACE: 1
MSBUILD_VERBOSITY: normal
Expand All @@ -31,7 +29,7 @@ env:
jobs:
# This workflow contains a single job called "Xaml-Style-Check"
Xaml-Style-Check:
runs-on: windows-latest-large
runs-on: windows-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
Expand Down
6 changes: 5 additions & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<Project>
<ItemGroup>
<!-- Workaround for WebView2 on uap pulling in Microsoft.VCLibs.Desktop when it shouldn't -->
<SDKReference Remove="Microsoft.VCLibs.Desktop, Version=14.0" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" Pack="false" />
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.12.1" PrivateAssets="all" Pack="false" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>

Expand Down
4 changes: 0 additions & 4 deletions Windows.Toolkit.Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,4 @@
<IsPublishable>true</IsPublishable>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(RepositoryDirectory)tooling\GlobalUsings.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace CommunityToolkit.AppServices.SourceGenerators;

Expand All @@ -18,10 +19,27 @@ private static class Helpers
/// Gets whether the current target is a UWP application.
/// </summary>
/// <param name="compilation">The input <see cref="Compilation"/> instance to inspect.</param>
/// <param name="analyzerOptions">The analyzer options to use to get info on the target application.</param>
/// <returns>Whether the current target is a UWP application.</returns>
public static bool IsUwpTarget(Compilation compilation)
public static bool IsUwpTarget(Compilation compilation, AnalyzerConfigOptions analyzerOptions)
{
return compilation.Options.OutputKind == OutputKind.WindowsRuntimeApplication;
// If the application type is a Windows Runtime application, then it's for sure a UWP app
if (compilation.Options.OutputKind == OutputKind.WindowsRuntimeApplication)
{
return true;
}

// Otherwise, the application is UWP if "UseUwpTools" is set
if (analyzerOptions.TryGetValue("build_property.UseUwpTools", out string? propertyValue))
{
if (bool.TryParse(propertyValue, out bool useUwpTools))
{
return true;
}
}

// The app is definitely not a UWP app
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Get all app service class implementations, and only enable this branch if the target is not a UWP app (the component)
IncrementalValuesProvider<(HierarchyInfo Hierarchy, AppServiceInfo Info)> appServiceComponentInfo =
context.SyntaxProvider
.CreateSyntaxProvider(
context.CreateSyntaxProviderWithOptions(
static (node, _) => node is ClassDeclarationSyntax classDeclaration && classDeclaration.HasOrPotentiallyHasBaseTypes(),
static (context, token) =>
{
// Only retrieve host info if the target is not a UWP application
if (Helpers.IsUwpTarget(context.SemanticModel.Compilation))
if (Helpers.IsUwpTarget(context.SemanticModel.Compilation, context.GlobalOptions))
{
return default;
}
Expand Down Expand Up @@ -80,14 +79,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

// Gather all interfaces, and only enable this branch if the target is a UWP app (the host)
IncrementalValuesProvider<(HierarchyInfo Hierarchy, AppServiceInfo Info)> appServiceHostInfo =
context.SyntaxProvider
.ForAttributeWithMetadataName(
context.ForAttributeWithMetadataNameAndOptions(
"CommunityToolkit.AppServices.AppServiceAttribute",
static (node, _) => node is InterfaceDeclarationSyntax,
static (context, token) =>
{
// Only retrieve host info if the target is a UWP application
if (!Helpers.IsUwpTarget(context.SemanticModel.Compilation))
if (!Helpers.IsUwpTarget(context.SemanticModel.Compilation, context.GlobalOptions))
{
return default;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace CommunityToolkit.AppServices.SourceGenerators.Extensions;

/// <summary>
/// <inheritdoc cref="GeneratorAttributeSyntaxContext" path="/summary/node()"/>
/// </summary>
/// <param name="syntaxContext">The original <see cref="GeneratorAttributeSyntaxContext"/> value.</param>
/// <param name="globalOptions">The original <see cref="AnalyzerConfigOptions"/> value.</param>
internal readonly struct GeneratorAttributeSyntaxContextWithOptions(
GeneratorAttributeSyntaxContext syntaxContext,
AnalyzerConfigOptions globalOptions)
{
/// <inheritdoc cref="GeneratorAttributeSyntaxContext.TargetNode"/>
public SyntaxNode TargetNode { get; } = syntaxContext.TargetNode;

/// <inheritdoc cref="GeneratorAttributeSyntaxContext.TargetSymbol"/>
public ISymbol TargetSymbol { get; } = syntaxContext.TargetSymbol;

/// <inheritdoc cref="GeneratorAttributeSyntaxContext.SemanticModel"/>
public SemanticModel SemanticModel { get; } = syntaxContext.SemanticModel;

/// <inheritdoc cref="GeneratorAttributeSyntaxContext.Attributes"/>
public ImmutableArray<AttributeData> Attributes { get; } = syntaxContext.Attributes;

/// <inheritdoc cref="AnalyzerConfigOptionsProvider.GlobalOptions"/>
public AnalyzerConfigOptions GlobalOptions { get; } = globalOptions;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace CommunityToolkit.AppServices.SourceGenerators.Extensions;

/// <summary>
/// <inheritdoc cref="GeneratorSyntaxContext" path="/summary/node()"/>
/// </summary>
/// <param name="syntaxContext">The original <see cref="GeneratorSyntaxContext"/> value.</param>
/// <param name="globalOptions">The original <see cref="AnalyzerConfigOptions"/> value.</param>
internal readonly struct GeneratorSyntaxContextWithOptions(
GeneratorSyntaxContext syntaxContext,
AnalyzerConfigOptions globalOptions)
{
/// <inheritdoc cref="GeneratorSyntaxContext.Node"/>
public SyntaxNode Node { get; } = syntaxContext.Node;

/// <inheritdoc cref="GeneratorSyntaxContext.SemanticModel"/>
public SemanticModel SemanticModel { get; } = syntaxContext.SemanticModel;

/// <inheritdoc cref="AnalyzerConfigOptionsProvider.GlobalOptions"/>
public AnalyzerConfigOptions GlobalOptions { get; } = globalOptions;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace CommunityToolkit.AppServices.SourceGenerators.Extensions;

/// <summary>
/// Extension methods for <see cref="IncrementalGeneratorInitializationContext"/>.
/// </summary>
internal static class IncrementalGeneratorInitializationContextExtensions
{
/// <inheritdoc cref="SyntaxValueProvider.ForAttributeWithMetadataName"/>
public static IncrementalValuesProvider<T> ForAttributeWithMetadataNameAndOptions<T>(
this IncrementalGeneratorInitializationContext context,
string fullyQualifiedMetadataName,
Func<SyntaxNode, CancellationToken, bool> predicate,
Func<GeneratorAttributeSyntaxContextWithOptions, CancellationToken, T> transform)
{
// Invoke 'ForAttributeWithMetadataName' normally, but just return the context directly
IncrementalValuesProvider<GeneratorAttributeSyntaxContext> syntaxContext = context.SyntaxProvider.ForAttributeWithMetadataName(
fullyQualifiedMetadataName,
predicate,
static (context, token) => context);

// Do the same for the analyzer config options
IncrementalValueProvider<AnalyzerConfigOptions> configOptions = context.AnalyzerConfigOptionsProvider.Select(static (provider, token) => provider.GlobalOptions);

// Merge the two and invoke the provided transform on these two values. Neither value
// is equatable, meaning the pipeline will always re-run until this point. This is
// intentional: we don't want any symbols or other expensive objects to be kept alive
// across incremental steps, especially if they could cause entire compilations to be
// rooted, which would significantly increase memory use and introduce more GC pauses.
// In this specific case, flowing non equatable values in a pipeline is therefore fine.
return syntaxContext.Combine(configOptions).Select((input, token) => transform(new GeneratorAttributeSyntaxContextWithOptions(input.Left, input.Right), token));
}

/// <inheritdoc cref="SyntaxValueProvider.CreateSyntaxProvider"/>
public static IncrementalValuesProvider<T> CreateSyntaxProviderWithOptions<T>(
this IncrementalGeneratorInitializationContext context,
Func<SyntaxNode, CancellationToken, bool> predicate,
Func<GeneratorSyntaxContextWithOptions, CancellationToken, T> transform)
{
// Invoke 'ForAttributeWithMetadataName' normally, but just return the context directly
IncrementalValuesProvider<GeneratorSyntaxContext> syntaxContext = context.SyntaxProvider.CreateSyntaxProvider(
predicate,
static (context, token) => context);

// Do the same for the analyzer config options
IncrementalValueProvider<AnalyzerConfigOptions> configOptions = context.AnalyzerConfigOptionsProvider.Select(static (provider, token) => provider.GlobalOptions);

// Merge the two and invoke the provided transform, like the extension above
return syntaxContext.Combine(configOptions).Select((input, token) => transform(new GeneratorSyntaxContextWithOptions(input.Left, input.Right), token));
}
}
4 changes: 2 additions & 2 deletions components/AppServices/src/AppServiceComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.AppServices.Helpers;

#pragma warning disable CA2213, CA1063
#pragma warning disable CA2213, CA1063, CsWinRT1028

namespace CommunityToolkit.AppServices;

Expand Down Expand Up @@ -462,7 +462,7 @@ private async void Connection_RequestReceived(AppServiceConnection sender, AppSe
try
{
// Try to get the registered endpoint with the command name, and invoke it
if (_endpoints.TryGetValue(commandStr, out Func<AppServiceParameters, Task<object?>> endpoint))
if (_endpoints.TryGetValue(commandStr, out Func<AppServiceParameters, Task<object?>>? endpoint) && endpoint is {})
{
response = await endpoint(new AppServiceParameters(this, sender, parameters));
}
Expand Down
6 changes: 3 additions & 3 deletions components/AppServices/src/AppServiceHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected AppServiceHost(string appServiceName)
private static bool CanUseAppServiceFunctionality { get; } = AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Desktop" && ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0);

/// <summary>
/// Handles the app service activation when <see cref="Windows.UI.Xaml.Application.OnBackgroundActivated(BackgroundActivatedEventArgs)"/> is invoked.
/// Handles the app service activation when <see cref="OnBackgroundActivated(BackgroundActivatedEventArgs)"/> is invoked.
/// </summary>
/// <param name="args">The args for the background activation.</param>
/// <returns>Whether this activation was an app service connection that could be handled by this host.</returns>
Expand Down Expand Up @@ -204,9 +204,9 @@ private void AppServiceConnection_RequestReceived(AppServiceConnection sender, A
if (args.Request.Message.TryGetValue(ProgressKey, out object? progressKey) &&
args.Request.Message.TryGetValue(ProgressValue, out object? progressValue) &&
progressKey is Guid id &&
_progressTrackers.TryGetValue(id, out IProgress<object> progress))
_progressTrackers.TryGetValue(id, out IProgress<object>? progress))
{
progress.Report(progressValue);
progress?.Report(progressValue);
}
}

Expand Down
14 changes: 6 additions & 8 deletions components/AppServices/src/CommunityToolkit.AppServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@
</PropertyGroup>

<!-- Add the Desktop Extension SDK when on UWP-->
<ItemGroup Condition="'$(IsUwp)' == 'true'">
<ItemGroup Condition="'$(IsUwp)' == 'true' AND $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'windows'">
<SDKReference Include="WindowsDesktop, Version=$(TargetPlatformVersion)">
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>

<!-- Add the contracts package reference to access WinRT APIs from .NET Standard -->
<ItemGroup Condition="'$(IsUwp)' != 'true'">
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.22621.2" />
<ItemGroup Condition="'$(IsNetstandard)' == 'true'">
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.26100.1742" />
</ItemGroup>

<!-- Source generator project reference for packing -->
Expand All @@ -49,13 +49,11 @@
<ItemGroup Label="Package">

<!-- Include the custom .targets file to check the source generator -->
<None Include="CommunityToolkit.AppServices.targets" PackagePath="buildTransitive\netstandard2.0" Pack="true" />
<None Include="CommunityToolkit.AppServices.targets" PackagePath="buildTransitive\uap10.0" Pack="true" />
<None Include="CommunityToolkit.AppServices.targets" PackagePath="build\netstandard2.0" Pack="true" />
<None Include="CommunityToolkit.AppServices.targets" PackagePath="build\uap10.0" Pack="true" />
<None Include="CommunityToolkit.Labs.AppServices.targets" PackagePath="buildTransitive" Pack="true" />
<None Include="CommunityToolkit.Labs.AppServices.targets" PackagePath="build" Pack="true" />

<!-- Pack the source generator to the right package folder -->
<None Include="..\CommunityToolkit.AppServices.SourceGenerators\bin\$(Configuration)\netstandard2.0\CommunityToolkit.AppServices.SourceGenerators.dll" PackagePath="analyzers\dotnet\cs" Pack="true" Visible="false" />
<None Include="..\CommunityToolkit.AppServices.SourceGenerators\bin\$(Platform)\$(Configuration)\netstandard2.0\CommunityToolkit.AppServices.SourceGenerators.dll" PackagePath="analyzers\dotnet\cs" Pack="true" Visible="false" />
</ItemGroup>

<!-- Remove imported global usings -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<Project>

<!-- Allow the source generators to detect whether an app on modern .NET is UWP or not -->
<ItemGroup>
<CompilerVisibleProperty Include="UseUwpTools" />
</ItemGroup>

<!-- Get the analyzer from the CommunityToolkit.AppServices NuGet package -->
<Target Name="CommunityToolkitAppServicesGatherAnalyzers">
<ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions components/CanvasView/src/CanvasView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#if NET8_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
#endif
using CommunityToolkit.Labs.WinUI.CanvasViewInternal;
using CommunityToolkit.WinUI.Helpers;

Expand Down Expand Up @@ -59,6 +62,9 @@ protected override void ClearContainerForItemOverride(DependencyObject element,
}
}

#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "These use of 'SetBindingExpressionValue' might be fine (we should revisit this later)")]
#endif
private void ContentPresenter_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// Move the rectangle.
Expand Down
8 changes: 4 additions & 4 deletions components/CanvasView/src/Dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
<Project>
<!-- WinUI 2 / UWP -->
<ItemGroup Condition="'$(IsUwp)' == 'true'">
<PackageReference Include="CommunityToolkit.Uwp.Helpers" Version="8.0.230907"/>
<PackageReference Include="CommunityToolkit.Uwp.Helpers" Version="8.2.241223-build.1367"/>
</ItemGroup>

<!-- WinUI 2 / Uno -->
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '2'">
<PackageReference Include="CommunityToolkit.Uwp.Helpers" Version="8.0.230907"/>
<PackageReference Include="CommunityToolkit.Uwp.Helpers" Version="8.2.241223-build.1367"/>
</ItemGroup>

<!-- WinUI 3 / WinAppSdk -->
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.0.230907"/>
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.241223-build.1367"/>
</ItemGroup>

<!-- WinUI 3 / Uno -->
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '3'">
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.0.230907"/>
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.241223-build.1367"/>
</ItemGroup>
</Project>
Loading
Loading