Visual Studioソリューションですべてのプロジェクトのターゲットフレームワークを変更する


104

すべてのプロジェクトのターゲットフレームワークを変更する必要があります。私は何百ものプロジェクトで多くのソリューションを持っています。

ここで何か新しいことや、すべてのプロジェクトを変更する必要がありますか?

回答:


37

これは、CodeProjectで利用可能なScott DormanのVisual Studioマクロを使用して行うことができます。

Visual Studio 2010とターゲットフレームワークのバージョン

以下はコードです。それを<UserProfile>\Documents\Visual Studio 2010\Projects\VSMacros80\MyMacrosフォルダーにダウンロードし、Visual Studio Macro 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

3
CodeProjectのリンクが機能しなくなったため、コードの+1。
Hannele 2012

81

複数の.Netプロジェクトを一度に変更するためのVisual Studio ExtensionであるTarget Framework Migratorを公開


これは2013年にはまだボールをプレーしていません。
Jon Egerton 2013年

1
VS 2013で機能するには、vsixmanifestでバージョン番号を1つ変更するだけでよい
Panagiotis Kanavos

この拡張機能は本当に時間の節約になります:)
合併

3
VS2015の場合:vsixmanifestでダウンロード、解凍、InstallationTargetのバージョンを14.0に、依存関係を4.6に変更
Jeroen K

5
VS2015と4.6をサポートする新しいバージョンがギャラリーにアップロードされました。
Pavel Samokha 2015

35

私が使用していた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
}

1
素晴らしいですが、私のシステムではエラーが発生したscript1.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policiesため、コマンドset-executionpolicy remotesignedを実行して修正しました。
kuncevic.dev 2013年

はい、ビッグ。システムでデフォルトでスクリプトを実行できないのは、私が当たり前のように感じている面倒です。ご指摘いただきありがとうございます。結局のところ、y'allをSet-ExecutionPolicy RemoteSigned使用すると、証明書に署名せずにローカルPowerShellスクリプトを実行できます。詳細については、こちらを参照してください: technet.microsoft.com/en-us/library/ee176961.aspx
Russell B

2
これはまさに私が探していたものです。これらすべての.projファイルを変更するための最もエレガントで柔軟なソリューション。
Ole Viaud-Murat 2015

1
私にとって、移行によってプロジェクトファイル、
app.configs

10

常にシンプルです。notepad ++などの適切なテキストエディターには、ファイル内の検索/置換機能が含まれます。csproj / vbprojファイルで現在のバージョン文字列を検索するだけです。

<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>

新しいバージョンに置き換えます

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>

最初にチェックアウトするのは良い考えですが...


1
これは私が見つけた最良の方法です
。Sublime


6

これを行う最も簡単な方法は、検索と置換ツールを使用することです。正規表現をサポートしている場合は利点です。

かなりの数がそこにあるに違いありません-私がテストした最初のものは私のためにうまくいきました:http : //www.ecobyte.com/replacetext/

Win7でいくつかの問題があるというメモがありますが、私はそれを経験していません。

そのツールのステップバイステップの説明:

  1. 置換| グループを追加| 名前を付けます(例:「MyGroup」)
  2. MyGroupを右クリック| 追加ファイル)...
  3. ソースを選択します(例:フォルダを使用、変更するプロジェクトのルートフォルダを参照)
  4. 必要に応じてインクルードファイルフィルターを設定します(例:* .csproj)
  5. 元のテキストの下の行を右クリックします| 高度な編集...
  6. 検索テキストボックスに正規表現を入力します(例<TargetFrameworkVersion>.*</TargetFrameworkVersion>
  7. 検索テキストの下のコンボボックスで「正規表現検索」を選択します
  8. 置換テキストを入力(例<TargetFrameworkVersion>4.0</TargetFrameworkVersion>
  9. 宛先とバックアップ設定を選択します(デフォルトでバックアップが作成されます)
  10. 交換を開始(Ctrl + R)

これで、何らかの理由でコードでこれを行う必要がある場合は、おそらく私もそれを行うことができます(このようにしてこの質問を見つけました)。その場合はコメントでお願いします。


ここに画像の説明を入力してください


はい、ShellShocksの回答の下にある0xA3のコメントを読みました。それが問題かもしれません。コード化されたソリューションに進む前に、その正規表現を考えてみます。
Mike Fuchs、


2

条件付きの正規表現が頭痛の種です。そこで、ここに検索/置換のコード化されたソリューションがあります(私は可能な限り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 (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;
        }
    }
}

1

マクロを使用してこれを行うことができます。または、VSプロジェクトファイルがテキストファイルであることを覚えておいてください。これは、単純なグローバル検索と置換で同じことができることを意味し、多くのプロジェクトファイルに同じ変更を加えるためのより一般的な手法です。

最初に既存のプロジェクトファイルをバックアップしてから、必要な変更を加えます(たとえば、ターゲットフレームワークを変更します)。WinDiffまたはWinMergeを使用して、新しいプロジェクトファイルをバックアップと比較します。これにより、必要な変更がわかります。次に、Visual Studio IDEのファイル内の検索と置換機能を使用して、すべてのプロジェクトファイルに変更を加えます。


2
ターゲットフレームワークを指定していないプロジェクトファイル(VS 2005で最初に作成されたファイルなど)の単純な検索と置換は失敗します。このようなプロジェクトファイルの場合、より複雑な検索と置換式でターゲットフレームワーク要素を挿入するための正しい位置を見つける必要があります。
Dirk Vollmar、2010年

0

外部ツールを使用しない代替手段(およびToolsVersionなどの他の設定を変更する機能):

  1. Visual Studioを使用して、新しいc#コンソールプロジェクト 'ManageCSProjFiles'(または任意の名前)を一時ディレクトリに作成します。「ソリューションとプロジェクトを同じディレクトリに配置する」を確認してください
  2. Program.csとProperties / AssemblyInfo.csをプロジェクトから削除します。プロジェクトをコンパイルする必要はありません。
  3. プロジェクトを保存してVisual Studioを閉じます。
  4. テキストエディターを使用してManageCSProjFiles.csprojを開きます。次の行を最後の行の前に追加します。
  <ItemGroup>
    <None Include="**\*.csproj" />
  </ItemGroup>
  1. ManageCSProjFiles.slnおよびManageCSProjFiles.csprojをソリューションツリーの最上位ディレクトリにコピーします。
  2. ManageCSProjFilesソリューションをVisual Studioにロードすると、すべての.csprojファイルが表示され、Visual Studioの検索/置換ツールでそれらを変更できます。

これは、他のプロジェクトタイプに簡単に拡張できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.