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 xunit testing in VS with the dispatcher #10023

Merged
merged 18 commits into from
Nov 11, 2024

Conversation

JeremyKuhne
Copy link
Member

@JeremyKuhne JeremyKuhne commented Oct 31, 2024

Enable xunit testing in VS with the dispatcher
This change enables writing and debugging unit tests in the Test Explorer in Visual Studio. I added a new test project for WindowsBase that has a unit test that launches the SplashScreen as an example.

In order to make this happen I had to reference the xunit.stafact package which introduced a number of challenges to overcome. The package has a reference to the desktop sdk and needs to be used in a project that targets net10.0-windows, not net10.0. To make everything work seamlessly I had to:

  • Strip the platform reference
  • Apply actual versions from the sdk
  • Get rid of AnyCPU and explictly use x86 (everything has a native dependency)
  • Enable transitive copying of references for the unit test projects
  • Target the 10.0 SDK (would get version confusion otherwise)
  • Add an override setting for WinForms which still targets the 9.0 SDK
  • Remove other targets that were trying to fixup WindowsBase references from the .NET SDK

This builds on #9914, which is included.

Microsoft Reviewers: Open in CodeFlow

@JeremyKuhne JeremyKuhne requested review from a team as code owners October 31, 2024 00:22
@dotnet-policy-service dotnet-policy-service bot added the PR metadata: Label to tag PRs, to facilitate with triage label Oct 31, 2024
eng/Versions.props Outdated Show resolved Hide resolved
@JeremyKuhne
Copy link
Member Author

Clearly there are some CI issues, but this does work locally. 🤷🏼 I'll be digging through that tomorrow. :)

@JeremyKuhne
Copy link
Member Author

The build machine is failing to load System.Text.Json when restoring. I can't reproduce this locally unfortunately.

Some general notes about why I updated to build against the .NET 10 SDK:

Despite installing and running the 9.0 SDK in the .dotnet folder, projects actually reference 10.0 via:

<MicrosoftNETCoreAppRefVersion>10.0.0-alpha.1.24528.7</MicrosoftNETCoreAppRefVersion>

and

<FrameworkReference Update="Microsoft.NETCore.App"
Condition="'$(MicrosoftNETCoreAppRefVersion)'!=''
And '$(NoTargets)'!='true'
And '$(TargetFrameworkIdentifier)' == '.NETCoreApp'
And $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '3.0'))
And '$(MSBuildProjectExtension)'!='.vcxproj'">
<TargetingPackVersion>$(MicrosoftNETCoreAppRefVersion)</TargetingPackVersion>
</FrameworkReference>

That means the output assemblies have a target framework of [assembly: TargetFramework(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] but all of the assembly references to the platform are 10.0.

Anything that brings in a reference with be keyed off of net9.0, but we have all 10.0 assemblies and assembly references. We can fix these up via a bit of whack-a-mole, but I'm not even sure what the runtime implications are. I'm experimenting a bit more to see if I can get all of the references implicitly pulled into the tests to be 10.0.

@JeremyKuhne
Copy link
Member Author

@lonitra could not repro the CI failure locally either.

@JeremyKuhne
Copy link
Member Author

The VS version on the CI machines needs to be updated to unblock this as the SDK we're trying to use has a newer version of MSBuild with an updated System.Text.Json dependency. Following up internally.

@JeremyKuhne JeremyKuhne force-pushed the enabletests branch 2 times, most recently from 3d10c7d to 441ce34 Compare November 10, 2024 01:32
@JeremyKuhne
Copy link
Member Author

Finally figured out how to get everything happy here. @ViktorHofer's fixes did enable me to backpedal on changing to 10.0. I struggled a bit with ARM until I figured out there was a race condition created by having the platform with multiple casings (ARM64 and arm64). 👀

JeremyKuhne added a commit to JeremyKuhne/wpf that referenced this pull request Nov 10, 2024
This updates SplashScreen to use direct interop built on CsWin32. It also uses the shared `System.Private.Windows.Core` library built in Windows Forms.

This makes SplashScreen trim-friendly and improves the performance as it will no longer need to generate the rather extensive interop it used to at startup.

This also introduces a bottom level assembly for WPF: `System.Windows.Primitives` where there are no other dependencies other than the WinForms/WPF base assembly: `System.Private.Windows.Core`.

`PInvokeCore` is the static class that comes from `System.Private.Windows.Core`. `PInvoke` is the static class from `System.Windows.Primitives`. When C# adds something akin to extension types (currently in the design phase) we'll be able to unify to a single `PInvoke`. Generated types (such as `HWND`) are in the namespaces as specified by the Windows metdata and don't have the same problem with conflicts as CsWin32 won't generate types that already exist.

CsWin32 uses `System.Drawing` types where they match Win32 types. `Point` is an example of this. These interchange `System.Drawing` types are in-box with .NET.

`System.Private.Windows.Core` provides a lot of useful support functionality, particularly when it comes to interop. The various scope types in this PR are an example. OLE code will come from this assembly after the new APIs are merged in WinForms.

I've also deleted a large swath of unused interop.

It leverages dotnet#10023, which leverages dotnet#9914 (the first commit), and will be updated when those are merged.

This is an update of dotnet#7929.
@JeremyKuhne
Copy link
Member Author

The key changes in this PR:

  • Makes the ref projects only reference the ref projects and makes them AnyCPU
  • Makes all implementation projects explicitly x86, x64, and arm64 (outside of PresentationBuildTasks, which remains AnyCPU)
  • Strips out references to the desktop platform in the unit tests to ensure we test what we build and avoid version conflicts
  • Establishes the pattern for using StaFact, which enables tests that require the dispatcher (UI)

(This took a while to finalize due to other infra issues.)

This removes the `NetCoreReference` infrastructure and replaces it with `DefaultReferenceExclusion` to remove the one problematic implicit reference to WindowsBase.

Manually picking references was blocking using System.Private.Windows.Core from the WinForms repo. Not having this also greatly simplifies the projects.

This also tweaks the solution to add folders docs and eng items.

Fixes dotnet#9168
This change enables writing and debugging unit tests in the Test Explorer in Visual Studio. I added a new test project for WindowsBase that has a unit test that launches the SplashScreen as an example.

In order to make this happen I had to reference the xunit.stafact package which introduced a number of challenges to overcome. The package has a reference to the desktop sdk and needs to be used in a project that targets `net10.0-windows`, not `net10.0`. To make everything work seamlessly I had to:

- Strip the platform reference
- Apply actual versions from the sdk
- Get rid of AnyCPU and explictly use x86 (everything has a native dependency)
- Enable transitive copying of references for the unit test projects
- Target the 10.0 SDK (would get version confusion otherwise)
- Add an override setting for WinForms which still targets the 9.0 SDK
- Remove other targets that were trying to fixup WindowsBase references from the .NET SDK
-
JeremyKuhne added a commit to JeremyKuhne/wpf that referenced this pull request Nov 11, 2024
This updates SplashScreen to use direct interop built on CsWin32. It also uses the shared `System.Private.Windows.Core` library built in Windows Forms.

This makes SplashScreen trim-friendly and improves the performance as it will no longer need to generate the rather extensive interop it used to at startup.

This also introduces a bottom level assembly for WPF: `System.Windows.Primitives` where there are no other dependencies other than the WinForms/WPF base assembly: `System.Private.Windows.Core`.

`PInvokeCore` is the static class that comes from `System.Private.Windows.Core`. `PInvoke` is the static class from `System.Windows.Primitives`. When C# adds something akin to extension types (currently in the design phase) we'll be able to unify to a single `PInvoke`. Generated types (such as `HWND`) are in the namespaces as specified by the Windows metdata and don't have the same problem with conflicts as CsWin32 won't generate types that already exist.

CsWin32 uses `System.Drawing` types where they match Win32 types. `Point` is an example of this. These interchange `System.Drawing` types are in-box with .NET.

`System.Private.Windows.Core` provides a lot of useful support functionality, particularly when it comes to interop. The various scope types in this PR are an example. OLE code will come from this assembly after the new APIs are merged in WinForms.

I've also deleted a large swath of unused interop.

It leverages dotnet#10023, which leverages dotnet#9914 (the first commit), and will be updated when those are merged.

This is an update of dotnet#7929.
eng/pipeline-pr.yml Outdated Show resolved Hide resolved
eng/pipeline-pr.yml Outdated Show resolved Hide resolved
@Kuldeep-MS Kuldeep-MS merged commit 25dd3ab into dotnet:main Nov 11, 2024
8 checks passed
JeremyKuhne added a commit to JeremyKuhne/wpf that referenced this pull request Nov 11, 2024
This updates SplashScreen to use direct interop built on CsWin32. It also uses the shared `System.Private.Windows.Core` library built in Windows Forms.

This makes SplashScreen trim-friendly and improves the performance as it will no longer need to generate the rather extensive interop it used to at startup.

This also introduces a bottom level assembly for WPF: `System.Windows.Primitives` where there are no other dependencies other than the WinForms/WPF base assembly: `System.Private.Windows.Core`.

`PInvokeCore` is the static class that comes from `System.Private.Windows.Core`. `PInvoke` is the static class from `System.Windows.Primitives`. When C# adds something akin to extension types (currently in the design phase) we'll be able to unify to a single `PInvoke`. Generated types (such as `HWND`) are in the namespaces as specified by the Windows metdata and don't have the same problem with conflicts as CsWin32 won't generate types that already exist.

CsWin32 uses `System.Drawing` types where they match Win32 types. `Point` is an example of this. These interchange `System.Drawing` types are in-box with .NET.

`System.Private.Windows.Core` provides a lot of useful support functionality, particularly when it comes to interop. The various scope types in this PR are an example. OLE code will come from this assembly after the new APIs are merged in WinForms.

I've also deleted a large swath of unused interop.

It leverages dotnet#10023, which leverages dotnet#9914 (the first commit), and will be updated when those are merged.

This is an update of dotnet#7929.
JeremyKuhne added a commit to JeremyKuhne/wpf that referenced this pull request Nov 14, 2024
…t also uses the shared `System.Private.Windows.Core` library built in Windows Forms.

This makes `SplashScreen` trim-friendly and improves the performance as it will no longer need to generate the rather extensive interop it used to at startup.

This also introduces a bottom level assembly for WPF: `System.Windows.Primitives` where there are no other dependencies other than the WinForms/WPF base assembly: `System.Private.Windows.Core`.

`PInvokeCore` is the static class that comes from `System.Private.Windows.Core`. `PInvoke` is the static class from `System.Windows.Primitives`. When C# adds something akin to extension types (currently in the design phase) we'll be able to unify to a single `PInvoke`. Generated types (such as `HWND`) are in the namespaces as specified by the Windows metdata and don't have the same problem with conflicts as CsWin32 won't generate types that already exist.

CsWin32 uses `System.Drawing` types where they match Win32 types. `Point` is an example of this. These interchange `System.Drawing` types are in-box with .NET.

`System.Private.Windows.Core` provides a lot of useful support functionality, particularly when it comes to interop. The various scope types in this PR are an example. OLE code will come from this assembly after the new APIs are merged in WinForms.

I've also deleted a large swath of unused interop.

It builds on dotnet#10023, which leverages dotnet#9914.

This is an update of dotnet#7929.
Kuldeep-MS pushed a commit that referenced this pull request Nov 15, 2024
* This updates `SplashScreen` to use direct interop built on CsWin32. It also uses the shared `System.Private.Windows.Core` library built in Windows Forms.

This makes `SplashScreen` trim-friendly and improves the performance as it will no longer need to generate the rather extensive interop it used to at startup.

This also introduces a bottom level assembly for WPF: `System.Windows.Primitives` where there are no other dependencies other than the WinForms/WPF base assembly: `System.Private.Windows.Core`.

`PInvokeCore` is the static class that comes from `System.Private.Windows.Core`. `PInvoke` is the static class from `System.Windows.Primitives`. When C# adds something akin to extension types (currently in the design phase) we'll be able to unify to a single `PInvoke`. Generated types (such as `HWND`) are in the namespaces as specified by the Windows metdata and don't have the same problem with conflicts as CsWin32 won't generate types that already exist.

CsWin32 uses `System.Drawing` types where they match Win32 types. `Point` is an example of this. These interchange `System.Drawing` types are in-box with .NET.

`System.Private.Windows.Core` provides a lot of useful support functionality, particularly when it comes to interop. The various scope types in this PR are an example. OLE code will come from this assembly after the new APIs are merged in WinForms.

I've also deleted a large swath of unused interop.

It builds on #10023, which leverages #9914.

This is an update of #7929.

* Make anonymous method static and remove orphaned file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR metadata: Label to tag PRs, to facilitate with triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants