将解决方案中的所有项目重新定位到.NET 4.5.2

115

我在Visual Studio 2012中有一个包含170个C#项目的解决方案。 我需要将所有项目从.NET Framework 4.0重定向到4.5.2。

我喜欢使用Visual Studio处理此操作,方法是进入每个项目的属性,更改目标框架,然后让Visual Studio对.csproj文件进行必要的更改。

我注意到这些更改包括根据当前项目的某些属性添加一些新的XML标签到.csproj中。

如何批量重定向所有170个C#项目,而不仅仅使用替换文本工具替换目标版本号?我希望Visual Studio进行所有必要的标记修改和添加,但单独使用替换无法实现。


我不知道有什么自动完成这个的方法。我认为你最好使用标准的Windows宏录制器,通过键盘命令来执行。但是,我建议你一个一个地执行它们,而不是尝试将它们批量处理在一起,因为在所有情况下识别VS何时完成工作可能会很困难。 - Erik Funkenbusch
2
不,你不应该这样做。特别是不要使用4.5.2版本,它没有有用的新类型,并且未来的多目标包也不太可能涵盖它。就像4.0x一样。一次只做一个项目,只处理那些需要它的项目。只有在你真正想要添加新的引用程序集并修改代码以使用它们的项目中才这样做。如果你想忽略这个建议,那么可以使用“编辑”>“查找和替换”>“在文件中替换”来替换*.csproj文件中的TargetFrameworkVersion元素。确保你的源代码控制是稳定的。 - Hans Passant
2
@HansPassant,根据我的问题,您提供的查找/替换解决方案恰恰是我不想要的。我需要一个更强大的解决方案。 - Kyle V.
@GrantWinney 我知道这样做行不通,因为我已经尝试过查找/替换,如果使用该方法,则 Visual Studio 否则会执行的其他 .csproj 更改未实现。 - Kyle V.
1
@GrantWinney,目标框架迁移器扩展程序正好符合我的要求。如果您能创建一个答案,我会将其标记为正确。谢谢! - Kyle V.
6个回答

100
MSDN文档"迁移到.NET Framework 4.5的迁移指南"和"如何配置应用程序以支持.NET Framework 4或4.5"仅讨论修改项目,没有关于一次性应用更改到整个解决方案的详细信息,我也没有看到VS中支持它的功能。然而,在Visual Studio Gallery中有一个(评价极高)扩展名为目标框架迁移器,支持升级到4.5.2(以及更新版本),看起来正好符合您的要求。如果您有兴趣,源代码可在GitHub上获得。请注意,缺少此类功能可能是故意的(不只是遗漏)。我猜想,微软认为只有需要新框架的项目才会升级。值得一提的是,如果您升级了与其他解决方案共享的某些项目,则这些解决方案在升级之前可能无法构建。话虽如此,如果您只有一个(或几个)解决方案的小型商店,并且希望一次性升级所有内容,则上述工具也许适合您。

多年来没有进行任何开发,显然开发者没有计划移交权力给其他人。

如果您无法在新版本的.NET Framework上使其正常工作,请检查现有的PRsIssues以获取修复方法,但您可能需要自行应用它们。例如,有人发布了一个针对.NET Framework v 4.7.1的修复程序。希望这些会被合并,但我不会抱太大的希望。

如果其他人也看到与Anas(在评论中)相同的错误,则这里有一个来自GitHub的问题,是几周前发布的,还有另一个可能相关的问题,则从2017年开始。如果您遇到了相同的问题,请考虑为它们点赞并添加更多细节。


7
“目标框架迁移工具”在最新的VS 2017更新15.5.5上失败,显示“无效参数”。 - Anas Ghanem
1
今天我在使用VS2017 15.7和Framework 4.7时成功运行了。 - Tod
1
我非常怀疑微软会有意为用户利益而省略功能...更有可能是他们没有考虑到或不必支持的其他事情...将其传递给社区.. - PJUK
1
@Grant 我给现有的问题添加了一个注释。实际上,我通过在项目和配置文件中进行查找/替换操作完成了这项工作。 - JB.
2
开发者在2019年12月交接了接力棒,你现在可以再次编辑你的(好的)回答 :) - Ludovic Feltz
显示剩余4条评论

20

对于一个.NET Framework解决方案,一个简单的“在文件中替换”对我很有帮助:

例如:从.NET Framework 4.5.2.NET Framework 4.7.2

package.config文件中,替换所有

targetFramework="net452" 

为了

targetFramework="net472" 

*.csproj 文件中,替换所有


<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> 

为了

<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>

1
在VS 2019中,“全部替换”功能不太靠谱。你必须重复使用“查找下一个”。这是我最后一个基于Microsoft的开发项目。我正在转向MacOSX,那里有一致性和相当程度的产品质量保证。 - ATL_DEV
2
在packages.config文件中更改targetFramework不会为该框架重新安装软件包,因此您仍然可能使用错误的版本。您必须重新安装软件包,或者至少删除packages文件夹并恢复正确版本的软件包。问题出在旧的packages.config模型上,如果不重新安装,则软件包的dll引用将针对软件包错误子目录中的错误dll。 - Triynko
3
哇,假期后又回到这个问题并发现需要对同一个答案进行评论,哈哈。我要补充的是,*.csproj和packages.config文件不是唯一引用目标框架的文件。在web.config文件的各个部分也有引用。例如,在system.web下,编译和httpRuntime标签有一个targetFramework属性需要更新。因此,这种“查找和替换”的手动过程似乎是一个非常糟糕的想法,可能会导致项目处于不一致和损坏的状态。 - Triynko

11

由于目标框架迁移工具存在问题,我自己编写了搜索/替换代码(使用git bash,在Windows上运行良好);它基本上将v4.6.x更改为v4.7.2,然后将文件转换回使用臭名昭著的DOS 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

5
我找到了这个问题,然后运行Update-Package -ReInstall就解决了。谢谢! - askrich
1
这对我来说完美地解决了问题。感谢您提供的解决方案。 - Maryam
有关Powershell版本,请参见https://dev59.com/EHE85IYBdhLWcg3wUByz#2837891 - tkerwood

7
我已经为自己建立了一个简单的工具,可以迁移整个解决方案的目标框架版本,因为目标框架迁移扩展不支持Visual Studio 2017。从我的GitHub代码库https://github.com/Xpitfire/TargetFrameworkMigrator下载该工具。
我知道这不是最佳实践,但它对我很有用,也许对其他人也会有所帮助。

现在它肯定可以了。 - Jay Croghan
1
这个建立在Java上的讽刺。 - Webreaper

4

目标框架迁移工具 非常实用。默认情况下,它支持 v4.7 版本。不过,很容易添加对 v4.7.1、v4.7.2 和 v4.8 版本的支持。

在 C:\Users{username}\AppData\Local\Microsoft\VisualStudio\ 文件夹中找到 Frameworks.xml 文件,并通过添加这些框架版本来进行编辑:

<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"/>

重新启动 Visual Studio 后,您将看到新的版本。


3
有一个分支与VS2019兼容的版本已经更新在https://github.com/Ian1971/TargetFrameworkMigrator/releases上。 - ScottS
非常感谢!这是一个非常好的和简单的解决方法! - merger
更新项目的目标框架后,您应该重新安装所有NuGet包。VS会提示这一点,但您也可以检查一下:(https://learn.microsoft.com/en-us/nuget/consume-packages/reinstalling-and-updating-packages) - Vasil Popov

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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接