Change the Target Framework for all my projects in a Visual Studio Solution
Solution 1
You can do that using Scott Dorman's Visual Studio macro available on CodeProject:
Below is the code, download it to your <UserProfile>\Documents\Visual Studio 2010\Projects\VSMacros80\MyMacros
folder, open the Visual Studio Macro IDE (Alt-F11) and add it as an existing item to the “MyMacros” project:
'------------------------------------------------------------------------------
' Visual Studio 2008 Macros
'
' ProjectUtilities.vb
'
'------------------------------------------------------------------------------
' Copyright (C) 2007-2008 Scott Dorman ([email protected])
'
' This library is free software; you can redistribute it and/or
' modify it under the terms of the Microsoft Public License (Ms-PL).
'
' This library is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' Microsoft Public License (Ms-PL) for more details.
'------------------------------------------------------------------------------
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Public Module ProjectUtilities
Private Class ProjectGuids
Public Const vsWindowsCSharp As String = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
Public Const vsWindowsVBNET As String = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"
Public Const vsWindowsVisualCPP As String = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
Public Const vsWebApplication As String = "{349C5851-65DF-11DA-9384-00065B846F21}"
Public Const vsWebSite As String = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}"
Public Const vsDistributedSystem As String = "{F135691A-BF7E-435D-8960-F99683D2D49C}"
Public Const vsWCF As String = "{3D9AD99F-2412-4246-B90B-4EAA41C64699}"
Public Const vsWPF As String = "{60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}"
Public Const vsVisualDatabaseTools As String = "{C252FEB5-A946-4202-B1D4-9916A0590387}"
Public Const vsDatabase As String = "{A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}"
Public Const vsDatabaseOther As String = "{4F174C21-8C12-11D0-8340-0000F80270F8}"
Public Const vsTest As String = "{3AC096D0-A1C2-E12C-1390-A8335801FDAB}"
Public Const vsLegacy2003SmartDeviceCSharp As String = "{20D4826A-C6FA-45DB-90F4-C717570B9F32}"
Public Const vsLegacy2003SmartDeviceVBNET As String = "{CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}"
Public Const vsSmartDeviceCSharp As String = "{4D628B5B-2FBC-4AA6-8C16-197242AEB884}"
Public Const vsSmartDeviceVBNET As String = "{68B1623D-7FB9-47D8-8664-7ECEA3297D4F}"
Public Const vsWorkflowCSharp As String = "{14822709-B5A1-4724-98CA-57A101D1B079}"
Public Const vsWorkflowVBNET As String = "{D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}"
Public Const vsDeploymentMergeModule As String = "{06A35CCD-C46D-44D5-987B-CF40FF872267}"
Public Const vsDeploymentCab As String = "{3EA9E505-35AC-4774-B492-AD1749C4943A}"
Public Const vsDeploymentSetup As String = "{978C614F-708E-4E1A-B201-565925725DBA}"
Public Const vsDeploymentSmartDeviceCab As String = "{AB322303-2255-48EF-A496-5904EB18DA55}"
Public Const vsVSTA As String = "{A860303F-1F3F-4691-B57E-529FC101A107}"
Public Const vsVSTO As String = "{BAA0C2D2-18E2-41B9-852F-F413020CAA33}"
Public Const vsSharePointWorkflow As String = "{F8810EC1-6754-47FC-A15F-DFABD2E3FA90}"
End Class
'' Defines the valid target framework values.
Enum TargetFramework
Fx40 = 262144
Fx35 = 196613
Fx30 = 196608
Fx20 = 131072
End Enum
'' Change the target framework for all projects in the current solution.
Sub ChangeTargetFrameworkForAllProjects()
Dim project As EnvDTE.Project
Dim clientProfile As Boolean = False
Write("--------- CHANGING TARGET .NET FRAMEWORK VERSION -------------")
Try
If Not DTE.Solution.IsOpen Then
Write("There is no solution open.")
Else
Dim targetFrameworkInput As String = InputBox("Enter the target framework version (Fx40, Fx35, Fx30, Fx20):", "Target Framework", "Fx40")
Dim targetFramework As TargetFramework = [Enum].Parse(GetType(TargetFramework), targetFrameworkInput)
If targetFramework = ProjectUtilities.TargetFramework.Fx35 Or targetFramework = ProjectUtilities.TargetFramework.Fx40 Then
Dim result As MsgBoxResult = MsgBox("The .NET Framework version chosen supports a Client Profile. Would you like to use that profile?", MsgBoxStyle.Question Or MsgBoxStyle.YesNo, "Target Framework Profile")
If result = MsgBoxResult.Yes Then
clientProfile = True
End If
End If
For Each project In DTE.Solution.Projects
If project.Kind <> Constants.vsProjectKindSolutionItems And project.Kind <> Constants.vsProjectKindMisc Then
ChangeTargetFramework(project, targetFramework, clientProfile)
Else
For Each projectItem In project.ProjectItems
If Not (projectItem.SubProject Is Nothing) Then
ChangeTargetFramework(projectItem.SubProject, targetFramework, clientProfile)
End If
Next
End If
Next
End If
Catch ex As System.Exception
Write(ex.Message)
End Try
End Sub
'' Change the target framework for a project.
Function ChangeTargetFramework(ByVal project As EnvDTE.Project, ByVal targetFramework As TargetFramework, ByVal clientProfile As Boolean) As Boolean
Dim changed As Boolean = True
If project.Kind = Constants.vsProjectKindSolutionItems Or project.Kind = Constants.vsProjectKindMisc Then
For Each projectItem In project.ProjectItems
If Not (projectItem.SubProject Is Nothing) Then
ChangeTargetFramework(projectItem.SubProject, targetFramework, clientProfile)
End If
Next
Else
Try
If IsLegalProjectType(project) Then
SetTargetFramework(project, targetFramework, clientProfile)
Else
Write("Skipping project: " + project.Name + " (" + project.Kind + ")")
End If
Catch ex As Exception
Write(ex.Message)
changed = False
End Try
End If
Return changed
End Function
'' Determines if the project is a project that actually supports changing the target framework.
Function IsLegalProjectType(ByVal proejct As EnvDTE.Project) As Boolean
Dim legalProjectType As Boolean = True
Select Case proejct.Kind
Case ProjectGuids.vsDatabase
legalProjectType = False
Case ProjectGuids.vsDatabaseOther
legalProjectType = False
Case ProjectGuids.vsDeploymentCab
legalProjectType = False
Case ProjectGuids.vsDeploymentMergeModule
legalProjectType = False
Case ProjectGuids.vsDeploymentSetup
legalProjectType = False
Case ProjectGuids.vsDeploymentSmartDeviceCab
legalProjectType = False
Case ProjectGuids.vsDistributedSystem
legalProjectType = False
Case ProjectGuids.vsLegacy2003SmartDeviceCSharp
legalProjectType = False
Case ProjectGuids.vsLegacy2003SmartDeviceVBNET
legalProjectType = False
Case ProjectGuids.vsSharePointWorkflow
legalProjectType = False
Case ProjectGuids.vsSmartDeviceCSharp
legalProjectType = True
Case ProjectGuids.vsSmartDeviceVBNET
legalProjectType = True
Case ProjectGuids.vsTest
legalProjectType = False
Case ProjectGuids.vsVisualDatabaseTools
legalProjectType = False
Case ProjectGuids.vsVSTA
legalProjectType = True
Case ProjectGuids.vsVSTO
legalProjectType = True
Case ProjectGuids.vsWCF
legalProjectType = True
Case ProjectGuids.vsWebApplication
legalProjectType = True
Case ProjectGuids.vsWebSite
legalProjectType = True
Case ProjectGuids.vsWindowsCSharp
legalProjectType = True
Case ProjectGuids.vsWindowsVBNET
legalProjectType = True
Case ProjectGuids.vsWindowsVisualCPP
legalProjectType = True
Case ProjectGuids.vsWorkflowCSharp
legalProjectType = False
Case ProjectGuids.vsWorkflowVBNET
legalProjectType = False
Case ProjectGuids.vsWPF
legalProjectType = True
Case Else
legalProjectType = False
End Select
Return legalProjectType
End Function
'' Sets the target framework for the project to the specified framework.
Sub SetTargetFramework(ByVal project As EnvDTE.Project, ByVal targetFramework As TargetFramework, ByVal clientProfile As Boolean)
Dim currentTargetFramework As TargetFramework = CType(project.Properties.Item("TargetFramework").Value, TargetFramework)
Dim targetMoniker As String = GetTargetFrameworkMoniker(targetFramework, clientProfile)
Dim currentMoniker As String = project.Properties.Item("TargetFrameworkMoniker").Value
If currentMoniker <> targetMoniker Then
Write("Changing project: " + project.Name + " from " + currentMoniker + " to " + targetMoniker + ".")
project.Properties.Item("TargetFrameworkMoniker").Value = targetMoniker
project.Properties.Item("TargetFramework").Value = targetFramework
Else
Write("Skipping project: " + project.Name + ", already at the correct target framework.")
End If
End Sub
Function GetTargetFrameworkMoniker(ByVal targetFramework As TargetFramework, ByVal clientProfile As Boolean) As String
Dim moniker As String = ".NETFramework,Version=v"
Select Case targetFramework
Case ProjectUtilities.TargetFramework.Fx20
moniker += "2.0"
Case ProjectUtilities.TargetFramework.Fx30
moniker += "3.0"
Case ProjectUtilities.TargetFramework.Fx35
moniker += "3.5"
Case ProjectUtilities.TargetFramework.Fx40
moniker += "4.0"
End Select
If clientProfile Then
moniker += ",Profile=Client"
End If
Return moniker
End Function
'' Writes a message to the output window
Sub Write(ByVal s As String)
Dim out As OutputWindowPane = GetOutputWindowPane("Change Target Framework", True)
out.OutputString(s)
out.OutputString(vbCrLf)
End Sub
'' Gets an instance of the output window
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
If show Then win.Visible = True
Dim ow As OutputWindow = win.Object
Dim owpane As OutputWindowPane
Try
owpane = ow.OutputWindowPanes.Item(Name)
Catch e As System.Exception
owpane = ow.OutputWindowPanes.Add(Name)
End Try
owpane.Activate()
Return owpane
End Function
End Module
Solution 2
Just published Target Framework Migrator, Visual Studio Extension for changing multiple .Net projects Target Framework at once
Solution 3
A PowerShell script that I used to do mine. Admittedly bruce force-ish.
Get-ChildItem . -Recurse -Filter *.*proj |ForEach {
$content = Get-Content $_.FullName
$content |ForEach {
$_.Replace("<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>", "<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>")
} |Set-Content $_.FullName
}
Solution 4
There's always the simple. A decent text editor such as notepad++ will include a find/replace in files function. Just search for the current version string in your csproj/vbproj files:
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
and replace with the new version
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
Good idea to check out first though...
Solution 5
From bash:
$find . -name "*.csproj" -exec sed -b -i "s,<TargetFrameworkVersion>[^<]*</TargetFrameworkVersion>,<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>," {} \;
Related videos on Youtube
Comments
-
Ezombort almost 4 years
I need to change the target framework for all projects. I have many solutions with hundreds of projects.
Anything new here or do I have to change every single project?
-
Dirk Vollmar about 14 yearsA simple search and replace will fail for project files that don't specify a target framework (e.g. files originally created in VS 2005). For such project files you would have to find the correct position to insert the target framework element with a more complicated search & replace expression.
-
Hannele over 11 years+1 for code, because the link on CodeProject doesn't appear to work any more.
-
Mike Fuchs over 11 yearsOk, I just read 0xA3's comment below ShellShocks answer. I suppose that might be a problem. I'll try to come up with a regular expression for it before going to the coded solution.
-
angularrocks.com over 11 yearsGreat but on my system i got an error
script1.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies
so i run commandset-executionpolicy remotesigned
to fix that. -
Russell B over 11 yearsYessirree, bigb. Not being able to run scripts by default on a system is a hassle I just sort of take for granted. Thanks for pointing that out. For all y'all
Set-ExecutionPolicy RemoteSigned
allows you to run local PowerShell scripts w/o cert-signing them. For details see here: technet.microsoft.com/en-us/library/ee176961.aspx -
Jon Egerton over 10 yearsThis isn't playing ball on 2013 yet.
-
Panagiotis Kanavos over 10 yearsOnly needs a single version number change in vsixmanifest to work in VS 2013
-
merger about 10 yearsThis extension is a real timesaver :)
-
ovm over 9 yearsThis is exactly what I have been looking for. Most elegant and flexible solution to change all those .proj files.
-
Jeroen K almost 9 yearsFor VS2015: download, unzip, in vsixmanifest: change InstallationTarget version to 14.0 and dependency to 4.6
-
DanielC almost 9 years@JeroenK Good tip, that's just what I was looking for. Unfortunately 4.6 isn't showing up in the framework list for this tool.
-
Pavel Samokha almost 9 years@DanielC Migrator's code available on github, feel free to change, compile, use, test and pull request. I currently have no time to do this (adding 4.6 n etc.) by myself.
-
Tomas Kubes almost 9 yearsFor me the migration modifies project files, app.configs and designers
-
Pavel Samokha over 8 yearsNew version with VS2015 and 4.6 support uploaded to gallery.
-
cuongle over 8 yearsI got problem with this tool when trying to upgrade to 4.5.2 in VS2015, our solution has 101 projects and this tool seems run forever, so I had to use Task Manager to stop it. Moreover, this tool changes to SOAP references, ex:
SalesForceReference.Reference.cs
toSalesForceReference.Reference.cs
, this is not correct. -
cuongle over 8 yearsThis is the best way that I found, I used Sublime to change all
-
Pavel Samokha over 8 years@CuongLe TFM doesn't change anything except framework - so if something changed, that's VS do it, not TFM. If project runs too long - that often caused by conflicts with other VS addins/plugins, try to disable them for a while.
-
Little Endian about 8 yearsDoesn't seem to recognize C++ projects.
-
Jose Parra about 7 yearsWorks like a charm on VS 2015!
-
Caius Jard almost 4 yearsIf, like me, you donwload the VSIX from VS marketplace and find it only goes up to .net 4.7, update your
%localappdata%\Microsoft\VisualStudio\VERSION\Extensions\APP_IF\Frameworks.xml
(use windows file search) using latest Frameworks.xml from the github project -
John Lewin almost 3 yearsSuch a cool option. When I do these steps I get all files in all projects loading as opposed to just the
.csproj
files. Ideally I have scenarios where I could use either behavior but I'm wondering if there's any simple step that might force it load the.csproj
files as simple text, as described above? Using VS 16.10.3 -
John Lewin almost 3 yearsIt took a while to realize this is just the result of my project being an SDK style
.csproj
which loads all content below the project. Adding a single default exclude statement creates the experience I was looking for:<DefaultItemExcludes>**/*;$(DefaultItemExcludes)</DefaultItemExcludes>