代码之家  ›  专栏  ›  技术社区  ›  Ezombort

在VisualStudio解决方案中更改我的所有项目的目标框架

  •  96
  • Ezombort  · 技术社区  · 14 年前

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

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

    9 回复  |  直到 12 年前
        1
  •  38
  •   Dirk Vollmar    14 年前

    您可以使用CodeProject上的Scott Dorman的Visual Studio宏来执行此操作:

    Visual Studio 2010 and Target Framework Version

    <UserProfile>\Documents\Visual Studio 2010\Projects\VSMacros80\MyMacros 文件夹中,打开Visual Studio宏IDE(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
    
        2
  •  81
  •   Pavel Samokha    12 年前
        3
  •  36
  •   Russell B    12 年前

    我以前用的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
    }
    
        4
  •  10
  •   Jon Egerton Aditya kumar sahoo    11 年前

    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    

    并替换为新版本

    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    

        5
  •  7
  •   Robert Jørgensgaard Engdahl    8 年前

    来自bash:

    $find . -name "*.csproj" -exec sed -b -i "s,<TargetFrameworkVersion>[^<]*</TargetFrameworkVersion>,<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>," {} \;
    
        6
  •  6
  •   Mike Fuchs Asif    12 年前

    我认为到目前为止最简单的方法是使用搜索和替换工具。如果它支持regex,这是一个优势。

    一定有不少人在那里-我测试的第一个为我工作,不过: http://www.ecobyte.com/replacetext/

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

    该工具中的逐步说明:

    1. 替换|添加组|命名(例如“MyGroup”)
    2. 右键单击MyGroup |添加文件。。。
    3. 选择源(例如,使用文件夹,浏览到要更改的项目的根文件夹)
    4. 如果需要,设置Include文件过滤器(例如.*.csproj)
    5. 右键单击原始文本下方的行|高级编辑。。。
    6. 在搜索文本框中输入正则表达式(例如。 <TargetFrameworkVersion>.*</TargetFrameworkVersion>
    7. 在搜索文本下方的组合框中选择“正则表达式搜索”
    8. <TargetFrameworkVersion>4.0</TargetFrameworkVersion> )
    9. 选择目标和备份设置(默认情况下将创建备份)


    enter image description here

        7
  •  5
  •   Randall Flagg    11 年前
        8
  •  2
  •   Community CDub    7 年前

    Conditional regexes 你让我头痛。所以这里有一个用于搜索/替换的编码解决方案(我尽量避免使用EnvDTE)。

    Order does not seem to matter 对于项目文件条目:

    试着这样做:

    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 (e.g. "v4.0")</param>
            /// <param name="rootDirectory">Root directory for the file search (e.g. "c:\Projects\2005")</param>
            /// <param name="fileSearchPattern">Pattern to find the project files (e.g. "*.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, e.g. "*.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;
            }
        }
    }
    
        9
  •  1
  •   Polyfun MicBehrens    14 年前

    您可以使用宏来执行此操作,或者记住VS project文件是文本文件,这意味着简单的全局搜索和替换可以实现相同的效果,并且是对许多项目文件进行相同更改的更通用的技术。

    首先备份现有的项目文件,然后进行所需的更改(例如,更改目标框架)。使用WinDiff或 WinMerge

        10
  •  0
  •   quietly-confident    4 年前

    没有外部工具(以及更改其他设置的能力,例如ToolsVersion)的替代方法:

    1. 使用Visual Studio,在临时目录中创建一个新的c#控制台项目“ManageCSProjFiles”(或任何您喜欢的名称)。确保选中“将解决方案和项目放在同一目录中”
    2. 从项目中删除Program.cs和Properties/AssemblyInfo.cs。没有必要编译这个项目。
    3. 保存项目并关闭VisualStudio。
    4. 使用文本编辑器打开ManageCSProjFiles.csproj。在最后一行之前的底部添加以下行:
      <ItemGroup>
        <None Include="**\*.csproj" />
      </ItemGroup>
    
    1. 将ManageCSProjFiles.sln和ManageCSProjFiles.csproj复制到解决方案树的最顶层目录。
    2. 如果在visualstudio中加载ManageCSProjFiles解决方案,它现在将显示所有的.csproj文件,您可以使用visualstudio中的搜索/替换工具更改它们。