在Visual Studio解决scheme中更改我的所有项目的目标框架

我需要改变所有项目的目标框架。 我拥有数百个项目的许多解决scheme。

这里有什么新东西,还是我必须改变每一个项目?

您可以使用CodeProject上提供的Scott Dorman的Visual Studiomacros来做到这一点:

Visual Studio 2010和Target Framework版本

下面是代码,下载到您的<UserProfile>\Documents\Visual Studio 2010\Projects\VSMacros80\MyMacros文件夹,打开Visual StudiomacrosIDE(Alt-F11),并将其作为现有项目添加到“MyMacros”项目:

 '------------------------------------------------------------------------------ ' Visual Studio 2008 Macros ' ' ProjectUtilities.vb ' '------------------------------------------------------------------------------ ' Copyright (C) 2007-2008 Scott Dorman (sj_dorman@hotmail.com) ' ' 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 

刚刚发布的Target Framework Migrator ,Visual Studio Extension,用于一次更改多个.Net项目Target Framework

一个PowerShell脚本,我曾经做我的。 不可否认的是,

 Get-ChildItem . -Recurse -Filter *.*proj |ForEach { $content = Get-Content $_.FullName $content |ForEach { $_.Replace("<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>", "<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>") } |Set-Content $_.FullName } 

总有那么简单。 一个象样的文本编辑器,如记事本+ +将包括查找/replace文件function。 只需在csproj / vbproj文件中search当前的版本string:

 <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> 

并用新版本replace

 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> 

好主意虽然首先检查出来…

我认为到目前为止最简单的方法是使用search和replace工具。 如果它支持正则expression式是有利的。

那里肯定有不less – 我testing的第一个为我工作,但: http : //www.ecobyte.com/replacetext/

有一个说明,它在Win7上有一些问题,但我没有经历过。

该工具中的分步说明:

  1. replace| 添加组| 将其命名(例如“MyGroup”)
  2. 右键单击MyGroup | 添加文件…
  3. select你的来源(例如使用文件夹,浏览到你想改变的项目的根文件夹)
  4. 根据需要设置包含文件filter(例如* .csproj)
  5. 右键单击“原始文本”下方的行 高级编辑…
  6. 在search文本框中input正则expression式(例如<TargetFrameworkVersion>.*</TargetFrameworkVersion>
  7. 在search文本下方的combobox中select“正则expression式search”
  8. inputreplace文本(例如<TargetFrameworkVersion>4.0</TargetFrameworkVersion>
  9. select目的地和备份设置(默认情况下会创build一个备份)
  10. 开始replace(Ctrl + R)

现在,如果由于某种原因,你需要在代码中这样做,我也可以做到这一点(这是我如何发现这个问题)。 在这种情况下,请在评论中提出要求。


在这里输入图像说明

Pavel Samokha提供的Target Framework Migrator(VHQLabs)

http://visualstudiogallery.msdn.microsoft.com/47bded90-80d8-42af-bc35-4736fdd8cd13

从bash:

 $find . -name "*.csproj" -exec sed -b -i "s,<TargetFrameworkVersion>[^<]*</TargetFrameworkVersion>,<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>," {} \; 

有条件的正则expression式让我头疼。 所以这里是一个search/replace的编码解决scheme(我尽可能避免EnvDTE)。

订单对于项目文件条目似乎并不重要 :

尝试一下:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; namespace TextReplaceDemo { class Program { static void Main(string[] args) { try { ReplaceTargetFrameworkVersion("v4.0", "c:/projekt/2005", "*.csproj"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } /// <summary> /// Inserts the denoted targetFramework into all occurrences of TargetFrameworkVersion. /// If the TargetFrameworkVersion is not present in the file, the method searches for the /// OutputType tag, which should be present, and inserts the TargetFrameworkVersion before that. /// </summary> /// <param name="targetFramework">New target framework (eg "v4.0")</param> /// <param name="rootDirectory">Root directory for the file search (eg "c:\Projects\2005")</param> /// <param name="fileSearchPattern">Pattern to find the project files (eg "*.csproj). /// Will get all files for empty parameter.</param> public static void ReplaceTargetFrameworkVersion(string targetFramework, string rootDirectory, string fileSearchPattern) { if (string.IsNullOrEmpty(targetFramework)) throw new ArgumentNullException("targetFramework"); if (string.IsNullOrEmpty(rootDirectory)) throw new ArgumentNullException("rootDirectory"); if (string.IsNullOrEmpty(fileSearchPattern)) fileSearchPattern = "*.*"; string regexPattern = "<TargetFrameworkVersion>.*</TargetFrameworkVersion>"; string insertText = string.Format("<TargetFrameworkVersion>{0}</TargetFrameworkVersion>", targetFramework); string alternativeMarker = "<OutputType>"; // get all files List<FileInfo> files = GetAllFiles(rootDirectory, fileSearchPattern); // iterate over found files foreach (var file in files) { string fileContent = File.ReadAllText(file.FullName); Match match = Regex.Match(fileContent, regexPattern); string newfileContent = null; if (match.Success) { // replace <TargetFrameworkVersion> newfileContent = fileContent.Replace(match.Value, insertText); } else if (fileContent.Contains(alternativeMarker)) { // create <TargetFrameworkVersion> newfileContent = fileContent.Replace(alternativeMarker, insertText + Environment.NewLine + " " + alternativeMarker); } // overwrite file if (newfileContent != null) File.WriteAllText(file.FullName, newfileContent); } } /// <summary> /// Recursive function to find all files in a directory by a searchPattern /// </summary> /// <param name="path">Path to the root directory</param> /// <param name="searchPattern">Pattern for the file search, eg "*.txt"</param> public static List<FileInfo> GetAllFiles(string path, string searchPattern) { List<FileInfo> files = new List<FileInfo>(); DirectoryInfo dir = new DirectoryInfo(path); if (dir.Exists) { // get all files in directory files.AddRange(dir.GetFiles(searchPattern)); // get all files of subdirectories foreach (var subDir in dir.GetDirectories()) { files.AddRange(GetAllFiles(subDir.FullName, searchPattern)); } } return files; } } } 

您可以使用macros来做到这一点,或记住,VS项目文件是文本文件,这意味着一个简单的全局search和replace可以实现相同的,是一个更一般的技术,使大量的项目文件相同的变化。

首先备份现有的项目文件,然后进行所需的更改(例如更改目标框架)。 使用WinDiff或WinMerge将新的项目文件与备份进行比较。 这将告诉你你需要做的改变。 然后使用Visual Studio IDE的“在文件中查找和replace”function对所有项目文件进行更改。