Skip to content

Commit b5d0ab6

Browse files
authored
Target Framework selector for F# App Property Page, now supports netcore and netstandard. (#6551)
1 parent ccb913d commit b5d0ab6

2 files changed

Lines changed: 56 additions & 19 deletions

File tree

vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/ApplicationPropPage.vb

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Imports VslangProj90
2222
Imports VslangProj100
2323
Imports System.Runtime.Versioning
2424
Imports Microsoft.VisualStudio.FSharp.ProjectSystem
25+
Imports Microsoft.VisualStudio.Shell
2526

2627
Namespace Microsoft.VisualStudio.Editors.PropertyPages
2728

@@ -362,6 +363,9 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
362363
OutputType = CType(value, VSLangProj.prjOutputType)
363364
Me.OutputType.SelectedIndex = OutputType
364365
PopulateControlSet(OutputType)
366+
367+
'Populate the target framework combobox
368+
PopulateTargetFrameworkAssemblies()
365369
Else
366370
'// We're indeterminate
367371
Me.OutputType.SelectedIndex = INDEX_INVALID
@@ -457,8 +461,6 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
457461
Me.Win32ResourceFileBrowse.Enabled = False
458462
End If
459463

460-
'Populate the target framework combobox
461-
PopulateTargetFrameworkAssemblies()
462464
' Populate list of possible versions of FSharp.Core
463465
PopulateAvailableFSharpCoreVersions()
464466
End Sub
@@ -503,6 +505,10 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
503505

504506
Me.PopulateControlSet(OutputType)
505507

508+
PopulateTargetFrameworkAssemblies()
509+
510+
SetDirty(VsProjPropId.VBPROJPROPID_OutputType, False)
511+
SetDirty(True) 'True forces Apply
506512
SetIconAndWin32ResourceFile()
507513
End Sub
508514

@@ -569,15 +575,19 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
569575
''' </summary>
570576
''' <remarks></remarks>
571577
Private Function ValidateTargetFrameworkMoniker(ByVal moniker As String) As Boolean
572-
If moniker = "" Or moniker = Nothing Then
578+
If String.IsNullOrWhiteSpace(moniker) Then
573579
Return False
574-
End If
575-
' .NET Core and .NETStandard don't need redists to be installed.
576-
If moniker.StartsWith(".NETCoreApp") OrElse moniker.StartsWith(".NETStandard") Then
577-
Return True
578-
End If
579-
' With the latest tooling, if we have editors the redist is installed by definition
580-
If moniker.Contains("v2") Or moniker.Contains("v3.0") Or moniker.Contains("v3.5") Or moniker.Contains("v4") Then
580+
ElseIf moniker.StartsWith(".NETCoreApp", StringComparison.OrdinalIgnoreCase) Then
581+
If Me.OutputType.SelectedIndex <> INDEX_INVALID Then ' NetCore always include
582+
' .NET Core and .NETStandard don't need redists to be installed.
583+
Return True
584+
End If
585+
ElseIf moniker.StartsWith(".NETStandard", StringComparison.OrdinalIgnoreCase) Then
586+
If Me.OutputType.SelectedIndex = 2 Then ' NetStandard ClassLibrary only
587+
Return True
588+
End If
589+
ElseIf moniker.Contains("v2") OrElse moniker.Contains("v3.0") OrElse moniker.Contains("v3.5") OrElse moniker.Contains("v4") Then
590+
' With the latest tooling, if we have editors the redist is installed by definition
581591
Return True
582592
End If
583593
Return False
@@ -612,7 +622,7 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
612622

613623
Private Sub PopulateAvailableFSharpCoreVersions()
614624
TargetFSharpCoreVersion.Items.Clear()
615-
TargetFSharpCoreVersion.SelectedIndex = -1
625+
TargetFSharpCoreVersion.SelectedIndex = INDEX_INVALID
616626

617627
Dim currentFrameworkName As FrameworkName = GetCurrentFrameworkName(DTEProject)
618628
Dim siteServiceProvider As Microsoft.VisualStudio.OLE.Interop.IServiceProvider = Nothing
@@ -647,21 +657,32 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
647657

648658
Private Sub PopulateTargetFrameworkAssemblies()
649659
Dim targetFrameworkSupported As Boolean = False
660+
Dim selectedItem As String = Nothing
661+
If Me.TargetFramework.SelectedIndex <> INDEX_INVALID Then
662+
selectedItem = Me.TargetFramework.Text
663+
End If
650664
Me.TargetFramework.Items.Clear()
651-
Me.TargetFramework.SelectedIndex = -1
665+
Me.TargetFramework.SelectedIndex = INDEX_INVALID
652666

653667
Try
654668
Dim sp As System.IServiceProvider = GetServiceProvider()
655669

656670
Dim vsFrameworkMultiTargeting As IVsFrameworkMultiTargeting = TryCast(sp.GetService(GetType(SVsFrameworkMultiTargeting)), IVsFrameworkMultiTargeting)
671+
Dim slnSvc As IVsSolution = TryCast(sp.GetService(GetType(SVsSolution)), IVsSolution)
672+
673+
Dim hier As IVsHierarchy = Nothing
674+
Dim isSdkProject = False
675+
If slnSvc.GetProjectOfUniqueName(DTEProject.UniqueName, hier) = 0 Then
676+
isSdkProject = hier.IsCapabilityMatch("CPS")
677+
End If
657678

658679
If vsFrameworkMultiTargeting IsNot Nothing Then
659680
Dim currentFrameworkName As FrameworkName = GetCurrentFrameworkName(DTEProject)
660681
Dim isPortable As Boolean = IsDotNetPortable(currentFrameworkName)
661682
targetFrameworkSupported = True
662683

663684
Dim supportedTargetFrameworksDescriptor As PropertyDescriptor = GetPropertyDescriptor("SupportedTargetFrameworks")
664-
Dim supportedFrameworks As IEnumerable(Of TargetFrameworkMoniker) = TargetFrameworkMoniker.GetSupportedTargetFrameworkMonikers(vsFrameworkMultiTargeting, DTEProject, supportedTargetFrameworksDescriptor)
685+
Dim supportedFrameworks As IEnumerable(Of TargetFrameworkMoniker) = TargetFrameworkMoniker.GetSupportedTargetFrameworkMonikers(vsFrameworkMultiTargeting, DTEProject, isSdkProject, supportedTargetFrameworksDescriptor)
665686

666687
For Each supportedFramework As TargetFrameworkMoniker In supportedFrameworks
667688
If Me.ValidateTargetFrameworkMoniker(supportedFramework.Moniker) Then
@@ -674,6 +695,12 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
674695
Next
675696

676697
End If
698+
699+
' Put back previous value
700+
If Not IsNothing(selectedItem) Then
701+
Me.TargetFramework.Text = selectedItem
702+
End If
703+
677704
Catch ex As Exception
678705
targetFrameworkSupported = False
679706
Me.TargetFramework.Items.Clear()
@@ -683,6 +710,7 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
683710
Me.TargetFramework.Enabled = False
684711
End If
685712
End Sub
713+
686714
Private Function SetTargetFSharpCore(ByVal control As Control, ByVal prop As PropertyDescriptor, ByVal value As Object) As Boolean
687715
Dim combobox As ComboBox = CType(control, ComboBox)
688716
combobox.SelectedIndex = INDEX_INVALID

vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/TargetFrameworkMoniker.vb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
7878
''' <param name="vsFrameworkMultiTargeting"></param>
7979
Public Shared Function GetSupportedTargetFrameworkMonikers(ByVal vsFrameworkMultiTargeting As IVsFrameworkMultiTargeting,
8080
ByVal currentProject As Project,
81+
isSdkProject As Boolean,
8182
ByVal supportedTargetFrameworksDescriptor As PropertyDescriptor) As IEnumerable(Of TargetFrameworkMoniker)
8283

8384
Dim supportedFrameworksArray As Array = Nothing
@@ -99,21 +100,29 @@ Namespace Microsoft.VisualStudio.Editors.PropertyPages
99100

100101
' Filter out frameworks with a different identifier since they are not applicable to the current project type
101102
Dim newFrameworkName As FrameworkName = New FrameworkName(moniker)
102-
If String.Compare(newFrameworkName.Identifier, currentFrameworkName.Identifier, StringComparison.OrdinalIgnoreCase) = 0 Then
103-
' Use DTAR to get the display name corresponding to the moniker
104-
Dim displayName As String = ""
103+
Dim displayName As String = ""
104+
105+
If isSdkProject Then
105106
If String.Compare(newFrameworkName.Identifier, ".NETStandard", StringComparison.Ordinal) = 0 OrElse
106107
String.Compare(newFrameworkName.Identifier, ".NETCoreApp", StringComparison.Ordinal) = 0 Then
107108
displayName = CStr(supportedTargetFrameworksDescriptor.Converter?.ConvertTo(moniker, GetType(String)))
109+
supportedTargetFrameworkMonikers.Add(New TargetFrameworkMoniker(moniker, displayName))
108110
Else
111+
If String.Compare(newFrameworkName.Identifier, ".NETFramework", StringComparison.OrdinalIgnoreCase) = 0 And newFrameworkName.Version >= New Version(4, 5, 0, 0) Then
112+
' Use DTAR to get the display name corresponding to the moniker
113+
VSErrorHandler.ThrowOnFailure(vsFrameworkMultiTargeting.GetDisplayNameForTargetFx(moniker, displayName))
114+
supportedTargetFrameworkMonikers.Add(New TargetFrameworkMoniker(moniker, displayName))
115+
End If
116+
End If
117+
Else
118+
If String.Compare(newFrameworkName.Identifier, currentFrameworkName.Identifier, StringComparison.OrdinalIgnoreCase) = 0 Then
119+
' Use DTAR to get the display name corresponding to the moniker
109120
VSErrorHandler.ThrowOnFailure(vsFrameworkMultiTargeting.GetDisplayNameForTargetFx(moniker, displayName))
121+
supportedTargetFrameworkMonikers.Add(New TargetFrameworkMoniker(moniker, displayName))
110122
End If
111-
112-
supportedTargetFrameworkMonikers.Add(New TargetFrameworkMoniker(moniker, displayName))
113123
End If
114124
End If
115125
Next
116-
117126
Return supportedTargetFrameworkMonikers
118127

119128
End Function

0 commit comments

Comments
 (0)