114

I have a solution in Visual Studio 2012 with 170 C# projects in it. I need to retarget all of the projects from .NET Framework 4.0 to 4.5.2.

I prefer to let Visual Studio handle this by going into the properties of each project, changing the targeted framework, and letting Visual Studio make any necessary changes to the .csproj files.

I noticed that these changes include adding a few new XML tags to the .csproj, depending on some attributes of the current project.

How can I batch retarget all 170 C# projects without just using a replace text tool to replace the targeted version number? I want Visual Studio to make all the necessary tag modifications and additions and replace alone will not permit that to happen.

Kyle V.
  • 4,752
  • 9
  • 47
  • 81
  • I don't know of any way to do this automatically.. I think your best bet would be a standard windows macro recorder, which you use keyboard commands.. But, I would execute these one at a time rather than try to batch them together since it may be difficult to identify when VS is done with its work in all cases. – Erik Funkenbusch Feb 10 '15 at 16:05
  • 2
    No, you should not be doing this. *Especially* not 4.5.2, it has no useful new types and is unlikely to be covered by future multi-targeting packs. Just like 4.0x wasn't. Do this *one* project at a time and only the ones that need it. The ones where you *actually* want to add a new reference assembly and modify the code to use them. If you want to ignore this advice, you probably do, then use Edit > Find and Replace > Replace in Files to replace the TargetFrameworkVersion element in the *.csproj files. Make sure your source control is solid. – Hans Passant Feb 10 '15 at 16:11
  • 2
    @HansPassant Your solution of Find/Replace is exactly what I didn't want to do according to my question. I need a more robust solution. – Kyle V. Feb 10 '15 at 16:20
  • @GrantWinney I /know/ it won't work because I already tried Find/Replace and if you use that method then the additional .csproj changes that Visual Studio would have done otherwise are not implemented. – Kyle V. Feb 10 '15 at 16:31
  • 1
    @GrantWinney the Target Framework Migrator extension does exactly what I wanted. If you can create an answer I will mark it correct. Thanks! – Kyle V. Feb 10 '15 at 16:58

6 Answers6

100

The MSDN documentation "Migration Guide to the .NET Framework 4.5" and "How to Configure an App to Support .NET Framework 4 or 4.5" only discusses modifying projects. There's no details on applying changes to the entire solution at once, nor have I seen a function in VS that supports it.

However, there's a (well-rated) extension called Target Framework Migrator available in the Visual Studio gallery, which supports upgrading to 4.5.2 (as well as newer versions**) and looks like it'll do exactly what you want. The source code is available on GitHub, if you're interested.

Note that the lack of such a feature may be intentional (and not just an omission). I'm just guessing, but maybe MS figures only projects that need the new Frameworks will be upgraded. FWIW, if you end up upgrading some projects that are shared with other solutions, those solutions may fail to build until they're upgraded too.

That being said, if you're in a small shop with just one (or a few) solutions and you're looking to upgrade everything in one go, then perhaps the above tool will work for you.


There's been no development on this for years, and apparently the developer has no plans to pass the baton to anyone else.

If you're unable to get it to work with a newer .NET Framework version, check the existing PRs and Issues for fixes, but you may have to apply them yourself. For example, someone posted a fix for .NET Framework v 4.7.1. Hopefully these will get merged, but I wouldn't hold my breath.

If anyone else is seeing the same error as Anas (in the comments), here's a GitHub issue from a couple weeks ago, and another possibly related issue from 2017. Consider thumbs upping them and adding more details if you're having the same problem.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • 7
    The "target framework migrator" tool is failing on latest VS 2017 update 15.5.5 , "Invalid parameter" – Anas Ghanem Feb 08 '18 at 08:28
  • 1
    Worked for me today with VS2017 15.7 to Framework 4.7 – Tod May 08 '18 at 14:50
  • 1
    I very much doubt that MS would intentionally omit features for users benefit... much more likely it is just something else they didn't think about or don't have to support... pass it on to the community.. – PJUK May 29 '18 at 13:09
  • It just completely fails to load and migrate to 4.7 : VS2017 v15.8 – JB. Sep 24 '18 at 13:52
  • 1
    @Grant I added a comment to the existing issue. I actually did the job with a find/sed search and replace in the project and config files. – JB. Sep 24 '18 at 15:22
  • FYI guys it doesn't support visual studio 2019 – Konstantin Malikov Nov 11 '19 at 09:59
  • 2
    The developer passed the baton on december 2019, you can edit your (good) answer again :) – Ludovic Feltz Feb 04 '20 at 15:55
  • Migrated to 4.7.2 in VS 2019. package on MarketPlace is outdated. Download and compile https://github.com/TargetFrameworkMigrator/TargetFrameworkMigrator VSIX project. You should see the VSIX extension in the ../bin/debug/ folder. It also includes the 4.8 Framework. – user2386411 Jul 08 '20 at 18:22
  • After updating the projects target framework, you should reinstall all nuget packages. VS will tell this if needed, but you can check this as well: https://learn.microsoft.com/en-us/nuget/consume-packages/reinstalling-and-updating-packages – Vasil Popov Sep 09 '21 at 08:32
19

For a .NET Framework solution, a simple "Replace in files" did the trick for me:

eg: From .NET Framework 4.5.2 to .NET Framework 4.7.2

In package.config files, replace all

targetFramework="net452" 

to

targetFramework="net472" 

In *.csproj files, replace all

<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> 

to

<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
webpat
  • 1,889
  • 16
  • 21
  • 1
    In VS 2019, "replace all" doesn't quite work. You have to repeatedly use "find next." This is my last Microsoft based development project. I am moving over to MacOSX where there's consistency and a decent level of QA performed on their products. – ATL_DEV Jan 11 '20 at 16:36
  • 2
    Changing the targetFramework in packages.config doesn't reinstall the package for that framework, so you could still end up with the wrong version. You'd have to reinstall the package, or at least delete your packages folder and restore the right version of the package. The problem is with that old packages.config model, without reinstalling, you're dll references for the package will be targeting the wrong dll in the wrong subdirectory of the package. – Triynko Jan 17 '20 at 02:41
  • 3
    Wow, ended up right back at this question again after vacation and also saw a need to comment on this same answer, haha. I will add that the *.csproj and packages.config files are not the only things that reference the target framework. There are also references in web.config files in various sections. For example, under system.web, the compilation and httpRuntime tags have a targetFramework attribute that would need updated. So, this 'find and replace' manual process seems like a really terrible idea that could leave your projects in inconsistent and corrupt state. – Triynko Jan 29 '20 at 19:16
11

Since the Target Framework Migrator is broken, I rolled my own search/replace (using git bash, it works ok on windows) ; Basically it changes the v4.6.x into v4.7.2, then it converts back the files to using the infamous DOS's CRLF :

find . \( -iname '*.csproj' -o -iname '*.vcxproj' -o -iname 'app.config' \) \
 -exec grep -Z -l 'v4\.6\..' \{} \; | xargs -0 sed -i 's/v4\.6\../v4.7.2/'  
find . \( -iname '*.csproj' -o -iname '*.vcxproj' -o -iname 'app.config' \) \
 -exec grep -Z -l 'v4\.7\..' \{} \; | xargs -0 unix2dos
JB.
  • 1,103
  • 1
  • 20
  • 37
7

I have built myself a simple tool to migrate the target framework versions for an entire solution, because the Target Framework Migrator Extension does not support Visual Studio 2017. Download the tool from my GitHub repository https://github.com/Xpitfire/TargetFrameworkMigrator

I know this is not the best way to go, but it worked for me and maybe it will also help someone else.

4

Target Framework Migrator is pretty useful. By default, it comes up to v4.7. However, it's easy to add support for v4.7.1, v4.7.2 and v4.8.

Find Frameworks.xml file in C:\Users{username}\AppData\Local\Microsoft\VisualStudio\ folder and edit by adding these framework versions:

<Framework Id="262152" Name=".NETFramework,Version=v4.8"/>
<Framework Id="262663" Name=".NETFramework,Version=v4.7.2"/>
<Framework Id="262407" Name=".NETFramework,Version=v4.7.1"/>

After you restart visual studio, you will see new versions.

Doğa Benli
  • 111
  • 1
  • 6
  • 3
    There is a fork w/ a VS2019 compatible release that is already updated at https://github.com/Ian1971/TargetFrameworkMigrator/releases – ScottS May 04 '20 at 04:10
  • Thanks alot! This was a very nice and easy workaround! – merger May 29 '20 at 09:02
  • After updating the projects target framework, you should reinstall all nuget packages. VS will tell this, but you can check this as well: ( https://learn.microsoft.com/en-us/nuget/consume-packages/reinstalling-and-updating-packages ) – Vasil Popov Sep 09 '21 at 08:31
2
public void ChangeFramework() {

  //Add Reference to envdte (Assemblies\Extensions\envDTE)
  string SolutionFile = @"C:\MyProject\MyProject.sln";
  string ProjectName = "MyProject";

  //------------------------------------------------------------------------
  //Find the Program ID from the registry for VisualStudio.DTE
  //Look it up In Registry: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Classes
  System.Type oType = System.Type.GetTypeFromProgID("VisualStudio.DTE", true);
  EnvDTE.DTE dte = (EnvDTE.DTE)Activator.CreateInstance(oType, true);

  //------------------------------------------------------------------------
  //Open your Solution
  dte.Solution.Open(SolutionFile);

  //------------------------------------------------------------------------
  //Now In your solution go through what is listed in dte.Solution.Projects 
  //and find the one that match what you want to change target for
  int iItemsCount = dte.Solution.Projects.Count;
  string sCurrent = "";

  for (int i = 1; i <= iItemsCount; i++) {

    sCurrent = dte.Solution.Projects.Item(i).Name;

    if (dte.Solution.Projects.Item(i).Name == ProjectName) {
      //Once you find your project, Change the Framework
      EnvDTE.Project oProject = dte.Solution.Projects.Item(i);
      oProject.Properties.Item("TargetFrameworkMoniker").Value = ".NETFramework,Version = v4.6.2";
    }
  }

  //------------------------------------------------------------------------
  //Close your Solution
  dte.Solution.Close();
}
vik_78
  • 1,107
  • 2
  • 13
  • 20
MaxR
  • 21
  • 1