dotnet / project-system

The .NET Project System for Visual Studio
MIT License
971 stars 389 forks source link

`UseWindowsForms` and `UseWPF` properties should be always available when targeting Windows #9098

Open reflectronic opened 1 year ago

reflectronic commented 1 year ago

It's common for libraries and console applications to use miscellaneous APIs from Windows Forms or WPF. In legacy-style projects, you would use "Add Reference" to add System.Windows.Forms to your application or library. Today it's not possible to do the same with SDK-style projects without manually editing the project file. Though we do expose UseWindowsForms and UseWPF in the project properties, they are only visible when the output type is WinExe (i.e. not a console application or library).

However, as of .NET 5, we have a more appropriate key for these properties—the target OS. We should change these properties to be visible when TargetPlatformIdentifier==Windows, rather than when OutputType==WinExe.

drewnoakes commented 1 year ago

This sounds like a good idea. @melytc do you think this would be straightforward to add?

melytc commented 1 year ago

I think this is a little bit more complex than it looks like: we use those properties to determine the project type we are dealing with, like in the CompountTargetFrameworkValueProvider: https://github.com/dotnet/project-system/blob/6e803bed90cc8de80db67329112cc97e689979ec/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/Properties/InterceptedProjectProperties/ApplicationPropertyPage/CompoundTargetFrameworkValueProvider.cs#L242

or the ApplicationFrameworkValueProvider: https://github.com/dotnet/project-system/blob/6e803bed90cc8de80db67329112cc97e689979ec/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Properties/InterceptedProjectProperties/ApplicationPropertyPage/ApplicationFrameworkValueProvider.cs#L134

We also use those properties to enable some capabilities, for example: https://github.com/dotnet/project-system/blob/6e803bed90cc8de80db67329112cc97e689979ec/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/DesignTimeTargets/Microsoft.VisualBasic.DesignTime.targets#L47

Let me think a little bit more through it, maybe we would have to change how we identify a project type; I want to make sure we don't break other areas by enabling this.

melytc commented 1 year ago

We could move to identifying project types by the combination of the OutputType and UseWPF/UseWindowsForms properties, like this:

WinForms (VB) = <UseWindowsForms>true</UseWindowsForms> + <OutputType>WinExe</OutputType> + <MyType>WindowsForms</MyType>

WinForms (C#) = <UseWindowsForms>true</UseWindowsForms> + <OutputType>WinExe</OutputType>

WPF (VB and C#) = <UseWPF>true</UseWPF> + <OutputType>WinExe</OutputType>

not sure if the distinction between VB/C# WinForms is needed, but I noticed that could be a differentiator.

melytc commented 1 year ago

After reviewing how the property is being used, is seems safe to proceed to implement this 🙂. Capabilities that use these properties are specifically for .NET Framework projects or the legacy properties pages. Classes where we check for these properties also check for the OutputType value to ensure it's a WPF/WinForms project.

Assigning myself to address it in 17.8, or earlier.