Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 56 additions & 0 deletions build/NuSpecs/Microsoft.WindowsAppSDK.ClassLibraryPublish.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Fix for WinUI ClassLibrary references during publish operations.
Without this, the build process incorrectly adds the runtime identifier to the class library reference path.

This target runs during any Publish operation to ensure ClassLibrary references are handled correctly
regardless of PublishSingleFile setting.
-->
<Target Name="FixClassLibraryReferencesForPublish"
BeforeTargets="_ComputeResolvedFilesToPublishList">

<!--
Modify the ResolvedFileToPublish items to ensure they're using the correct paths without runtime identifiers
for class library references during publish operations.
-->
<ItemGroup>
<ResolvedFileToPublish Condition="'%(ResolvedFileToPublish.AssetType)' == 'runtime'
AND '%(ResolvedFileToPublish.RuntimeIdentifier)' != ''
AND $([System.String]::Copy('%(ResolvedFileToPublish.SourcePath)').Contains('%(ResolvedFileToPublish.RuntimeIdentifier)'))">
<DestinationSubPath>$(PublishDir)%(ResolvedFileToPublish.DestinationSubPath)</DestinationSubPath>
</ResolvedFileToPublish>
</ItemGroup>

<!--
Check if any class library references need to have their paths corrected by looking for files
that should exist in the non-runtime-specific folder instead.
-->
<ItemGroup>
<_PublishItemsToCheck Include="@(ResolvedFileToPublish)"
Condition="'%(ResolvedFileToPublish.AssetType)' == 'runtime'
AND '%(ResolvedFileToPublish.RuntimeIdentifier)' != ''
AND $([System.String]::Copy('%(ResolvedFileToPublish.SourcePath)').Contains('%(ResolvedFileToPublish.RuntimeIdentifier)'))" />

<_MissingRuntimeFiles Include="@(_PublishItemsToCheck)"
Condition="!Exists('%(SourcePath)')" />
</ItemGroup>

<!-- For any missing files, look for them in the non-runtime-specific location -->
<ItemGroup>
<_NonRIDSourcePaths Include="@(_MissingRuntimeFiles->'$([System.String]::Copy('%(SourcePath)').Replace('\%(RuntimeIdentifier)\', '\'))')">
<OriginalItem>%(_MissingRuntimeFiles.Identity)</OriginalItem>
</_NonRIDSourcePaths>
</ItemGroup>

<!-- Update the ResolvedFileToPublish items with the corrected SourcePath -->
<ItemGroup>
<ResolvedFileToPublish Remove="@(_MissingRuntimeFiles)" />
<ResolvedFileToPublish Include="@(_NonRIDSourcePaths->'%(OriginalItem)')"
Condition="Exists('%(Identity)')">
<SourcePath>%(Identity)</SourcePath>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
</Project>
3 changes: 3 additions & 0 deletions build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.AutoInitializerCommon.targets" />
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.AutoInitializer.CS.targets" Condition="'$(WindowsAppSdkAutoInitialize)' == 'true'"/>

<!-- Import the ClassLibraryPublish fix for WinUI class library references -->
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.ClassLibraryPublish.targets" />

<ItemGroup>
<Compile Condition="'$(WindowsAppSDKAggregatePackage)' == 'true' and '$(WindowsAppSdkIncludeVersionInfo)'=='true'" Include="$(MSBuildThisFileDirectory)..\include\WindowsAppSDK-VersionInfo.cs" />
</ItemGroup>
Expand Down
43 changes: 43 additions & 0 deletions docs/Packaging/WinUI-ClassLibrary-References.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# WinUI ClassLibrary References During Publish

## Issue

When using the Windows App SDK with a project that references a WinUI class library, the build process incorrectly looks for the class library in a path that includes the runtime identifier (e.g., `win-x64`), which causes build failures. This occurs in any publish scenario, including when using `PublishSingleFile=true`.

For example, if your solution structure is:
```
Solution
├── App1 (references ClassLibrary1)
└── ClassLibrary1
```

When publishing App1, you might encounter errors like:
```
Cannot resolve Assembly or Windows Metadata file 'path\to\ClassLibrary1\bin\Release\net8.0-windows10.0.19041.0\win-x64\ClassLibrary1.dll'
Metadata file 'path\to\ClassLibrary1\bin\Release\net8.0-windows10.0.19041.0\win-x64\ClassLibrary1.dll' could not be found
```

## Solution

The fix implemented in `Microsoft.WindowsAppSDK.ClassLibraryPublish.targets` addresses this issue by correcting the reference paths during the publish process.

The target does the following:
1. Runs before the `_ComputeResolvedFilesToPublishList` target during any publish operation
2. Identifies class library references that include runtime identifiers in their paths
3. Checks if the files exist at the specified paths
4. For missing files, tries to find them in the non-runtime-specific location
5. Updates the `ResolvedFileToPublish` items with the corrected paths

## Workaround (prior to this fix)

If you encounter this issue before updating to a version with this fix, you can:

1. Create a Blank Project
2. Create a Blank Class Library
3. Add Class Library Reference to Main Project
4. Build
5. Manually modify the Class Library output folder:
- Create a folder named after your runtime identifier (e.g., `win-x64`) in the output directory
- Copy all files from the main output directory into this new folder

This mimics the file structure expected by the publish process.