用NuGet引用替换数百个项目中的二进制引用

4
考虑一个大型现有代码库,其中有大约150多个解决方案和800多个C#项目。许多是使用NUnit编写的单元测试。所有这些项目都从“lib”文件夹引用“nunit.framework.dll”,该文件夹已被检入。还有一些第三方程序集在“lib”文件夹中,具有相应的NuGet软件包。
我可以手动打开150多个解决方案并迁移每个引用到NuGet。然而,这证明是繁琐且容易出错的。我编写了一个C#控制台应用程序来解析csproj文件并确定需要安装哪些软件包以供各自的项目使用。因此,我知道300多个项目需要安装NUnit软件包。
如何以编程方式自动安装解决方案中的软件包,并与在Visual Studio 2013中手动执行完全相同的行为匹配?我到处寻找,只找到一个extension,但它不会执行具有依赖项等的完整安装。

1
可能是NuGet:自动迁移对包的引用的重复问题。 - Owen Pauling
@bloudraak,我即将开始一个类似的任务 - 你的控制台应用程序代码发布在哪里了吗? - fiat
2个回答

3
您可以使用以下片段:
Get-Project -All | foreach-object {IF (Get-Content $_.FullName | Select-String 'Reference Include="XXX"') {Install-Package XXX -ProjectName $_.FullName}}

XXX替换为您想要的软件包名称,并在Visual Studio中的Tools->NuGet Package Manager->Package Manager Console中运行代码片段。

起初我尝试了开箱即用的方法,但后来我意识到“Reference Include =“XXX””是csproj文件的内容。在我的情况下,这在所有地方都是相同的.. \ ProjName \ ProjName,而且你需要 \ 而不是一个 \。如果它们没有在相同的结构中引用,那么很容易找到每个csproj中关于此引用的写法。这仍然需要几个调用。是的,它可以工作。我很高兴。 - user6110389

3
创建一个只包含NUnit包条目的packages.config文件
package.config应该类似于以下内容,请检查正确的包名称、版本和目标信息。
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="nunit.framework" version="2.6.3" targetFramework="net45" requireReinstallation="true" />
</packages>

扩展你编写的解析.csproj文件的工具,
以便也可以编辑csproj文件并添加以下标签

  <ItemGroup>
    <None Include="packages.config" />
  </ItemGroup>

需要将packages.config文件复制到所有项目文件夹中;如果你的项目将使用相同的引用,可以选择将packages.config作为链接添加。

 <ItemGroup>
    <None Include="$(SolutionDir)packages.config">
       <Link>$(SolutionDir)packages.config</Link>
    </None>
  </ItemGroup>

完成此操作后,在Visual Studio中打开解决方案,转到NuGet控制台并输入以下命令; NuGet将解决缺少的依赖项并添加它们。

update-package

我猜测命令行 nuget update <solution> 可以在更新解决方案中的所有项目后完成任务,我的理解是否正确? - bloudraak
我的假设不起作用。项目文件没有被修改,因为已经还原的软件包已经是最新的。 - bloudraak
建议的过程似乎效果不佳。调用“Update-Package”不会将二进制引用更改为NuGet引用,如果您不指定包ID,则会将现有包升级到不兼容的版本。当使用“Update-Package -Reinstall -Safe”时,有时会删除软件包并且项目无法编译。在其他情况下,该过程将失败并出现COM错误。对于大型解决方案,此过程还需要很长时间;对于我的某些解决方案,需要长达两个小时(这往往会失败或产生不正确的结果)。 - bloudraak

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