Package ijwhost.dll as native asset for self-contained publish#11664
Package ijwhost.dll as native asset for self-contained publish#11664mmanolova-msft wants to merge 1 commit into
Conversation
After the /clr:pure to /clr:NetCore migration (dotnet#11575), DirectWriteForwarder and System.Printing became mixed-mode C++/CLI assemblies that require ijwhost.dll at runtime. The DLL was being placed in the managed lib/ folder where it is not recognized by RuntimeList.xml, causing it to be missing from self-contained publish output. Exclude ijwhost.dll from the lib/ packaging and add it as a native asset under runtimes/win-{arch}/native/ so it is properly included in the runtime pack manifest. Fixes dotnet#11651 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a regression in WPF self-contained publish by ensuring ijwhost.dll (required to load IJW mixed-mode C++/CLI assemblies) is packaged as a native runtime asset rather than ending up under the managed lib/ folder, which prevents it from being picked up for self-contained publish.
Changes:
- Excludes
ijwhost.dllfrom the default$(OutDir)*.dllmanaged (lib/) packaging glob. - Adds a packaging target in both mixed-mode projects to include
ijwhost.dllunderruntimes/win-{arch}/native/.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Microsoft.DotNet.Wpf/src/System.Printing/System.Printing.vcxproj | Excludes ijwhost.dll from lib/ packaging and adds it as a native runtime asset under runtimes/win-{arch}/native/. |
| src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/DirectWriteForwarder.vcxproj | Same packaging adjustment as System.Printing to ensure ijwhost.dll is treated as a native asset for self-contained publish. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@dotnet-policy-service agree company="Microsoft" |
Self-contained WPF apps crash due to missing ijwhost.dll. The fix is tracked in dotnet/wpf#11664. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
| Scenario | This PR fixes? | Additional fix needed? |
|---|---|---|
| Self-contained publish | ✅ Yes | — |
| Framework-dependent | ✅ N/A (never broken) | — |
| Single-file publish | ❌ No | DropFromSingleFile="true" in dotnet/windowsdesktop sfxproj |
@mmanolova-msft please validate this once. The changes you made for self-contained looks good.
Self-contained WPF apps crash due to missing ijwhost.dll. The fix is tracked in dotnet/wpf#11664. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| <!-- | ||
| Exclude ijwhost.dll from the managed (lib/) folder packaging. | ||
| It must be placed in runtimes/win-{arch}/native/ instead so that it is | ||
| recognized as a native asset and included in RuntimeList.xml for | ||
| self-contained publish scenarios. | ||
| --> | ||
| <ItemGroup> | ||
| <FileNamesExcludedFromPackaging Include="ijwhost.dll" /> | ||
| </ItemGroup> | ||
| <Target Name="_PackageIjwHostAsNativeAsset" BeforeTargets="CopyPackageAssets" AfterTargets="IdentifyPackageAssets" Condition="'$(PackageName)'!='' and Exists('$(OutDir)ijwhost.dll')"> | ||
| <PropertyGroup> | ||
| <_IjwHostNativeDestFolder Condition="'$(Platform)'=='AnyCPU' or '$(Platform)'=='x86' or '$(Platform)'=='Win32'">runtimes\win-x86\native\</_IjwHostNativeDestFolder> | ||
| <_IjwHostNativeDestFolder Condition="'$(Platform)'=='x64'">runtimes\win-x64\native\</_IjwHostNativeDestFolder> | ||
| <_IjwHostNativeDestFolder Condition="'$(Platform)'=='arm64'">runtimes\win-arm64\native\</_IjwHostNativeDestFolder> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <PackageAsset Include="$(OutDir)ijwhost.dll" RelativePath="$(ArtifactsPackagingDir)$(NormalizedPackageName)\$(_IjwHostNativeDestFolder)" /> | ||
| </ItemGroup> | ||
| </Target> |
There was a problem hiding this comment.
Since this is same as the one in DirectWriteForwader, I suggest we have this in a common place which these two files use. It would help us avoid missing updating individually if we face these types of regression later again.
| </ItemGroup> | ||
| <Target Name="_PackageIjwHostAsNativeAsset" BeforeTargets="CopyPackageAssets" AfterTargets="IdentifyPackageAssets" Condition="'$(PackageName)'!='' and Exists('$(OutDir)ijwhost.dll')"> | ||
| <PropertyGroup> | ||
| <_IjwHostNativeDestFolder Condition="'$(Platform)'=='AnyCPU' or '$(Platform)'=='x86' or '$(Platform)'=='Win32'">runtimes\win-x86\native\</_IjwHostNativeDestFolder> |
There was a problem hiding this comment.
nit: we can simplify it further by moving it down after x64 and arm64. After x64 and arm64, if the value is still not set, we can keep it as x86. Better readability and avoid multiple platform conditions.
|
Agree, with Dipesh's comments. |


Fixes #11651
Main PR: N/A (this is the main branch fix)
Description
After PR #11575 migrated C++/CLI projects from
/clr:pureto/clr:NetCore,DirectWriteForwarder.dllandSystem.Printing.dllbecame mixed-mode assemblies requiringijwhost.dllat runtime. The build was placingijwhost.dllin the managedlib/net11.0/folder (via the$(OutDir)*.dllglob), where it is not recognized byRuntimeList.xml. This caused it to be missing from self-contained publish output.The fix excludes
ijwhost.dllfrom lib/ folder packaging and adds a target to place it inruntimes/win-{arch}/native/where it is properly listed in the runtime pack manifest.Customer Impact
Any WPF app published as self-contained (
dotnet publish -r win-x64 --self-contained) crashes on launch with:Framework-dependent apps are unaffected (they load from the shared framework folder).
Regression
Yes. Introduced by #11575 (Remove /clr:pure from WPF C++/CLI projects), which shipped in SDK 11.0.100-preview.5.26264.105. Not present in 11.0.100-preview.5.26263.112.
Testing
build.cmd -c Release -platform x64 -pack)ijwhost.dlllands inruntimes/win-x64/native/(notlib/net11.0/)dotnet publish --self-containedincludesIjwhost.dllin outputRisk
Low. The change only affects packaging of
ijwhost.dll— moving it from an incorrect location (lib/) to the correct one (native/). This matches how all other native DLLs (vcruntime140_cor3.dll, wpfgfx_cor3.dll, etc.) are already packaged.Microsoft Reviewers: Open in CodeFlow