如何在Visual Studio之外使用NuGet包管理器通过命令行安装/更新软件包?

6
我正在使用微服务架构,核心代码通过Nuget包共享。这一切都很顺利,除了偶尔需要更新一个核心Nuget包并将其更新到10多个解决方案的最新版本之外。由于Visual Studio需要很长时间才能加载,我不想每次都打开每个解决方案并从Nuget包管理器运行Update-Package命令。
我尝试使用Nuget.exe命令行,但安装选项只下载包而不是将其安装到我的项目中。我已经尝试搜索如何在Visual Studio之外运行包管理器,但最接近的是两年半前的这篇文章,其中提到它已在路上,但链接已过时。我也不熟悉在这个网站上请求更新的工作方式。
有没有人知道是否有我错过的Nuget功能?如果没有,有没有人知道在不必每次等待可怕的Visual Studio加载时间的情况下更新多个解决方案的Nuget包的替代方法?

Nuget cli怎么样?https://docs.nuget.org/ndocs/tools/nuget.exe-cli-reference 回答太短了:P - TigOldBitties
2
执行“nuget install My.Nuget.Package”只会将其下载到我的解决方案的packages/文件夹中。它实际上不会更新packages.json文件中对该包的任何用法,也不会更新csproj文件中的提示路径。虽然手动更新这两个文件可能比打开Visual Studio更快,但容易出错(而我以犯错误著称)。 - Paul Milla
1
为什么拥有一个简单的VS快捷方式来编辑VS外的文件是荒谬的?"nuget.exe install",更具体地说是"nuget.exe update"可以让我完成大部分工作。真正剩下的事情只是让"install"命令在packages.config/.csproj文件中添加一个条目,并让"update"命令更新.csproj文件中的hintpath。我可以编写一个快速脚本来运行命令并执行我想要的操作,但我认为这个问题现在应该已经得到解决,而且在没有立即找到解决方案后,我想问问其他人是否遇到过这个问题。 - Paul Milla
1个回答

7

我最终编写了一个快速解决我的问题的PowerShell脚本。以下是脚本,如果有其他人感兴趣:

param(
    [Parameter(Mandatory=$true)]$package,
    $solution = (Get-Item *.sln),
    $nuget = "nuget.exe"
)

& $nuget update "$solution" -Id "$package"

$sln = Get-Content $solution
[regex]$regex = 'Project\("{.*?}"\) = ".*?", "(.*?\.csproj)", "{.*?}"'
$csprojs = $sln | Select-String $regex -AllMatches | 
                  % {$_.Matches} |
                  % {$_.Groups[1].Value}

Foreach ($csproj_path in $csprojs) {
    $csproj_path = Get-Item $csproj_path
    Write-Host "Updating csproj: $csproj_path"

    [xml]$csproj = Get-Content $csproj_path
    Push-Location (Get-Item $csproj_path).Directory
    $reference = $csproj.Project.ItemGroup.Reference | ? {$_.Include -like "$package,*"}

    $old_include = [string]$reference.Include
    $old_hintpath = [string]$reference.HintPath
    $old_version = $old_include | Select-String 'Version=([\d\.]+?),' |
                                  % {$_.Matches} |
                                  % {$_.Groups[1].Value}

    $all_packages = Get-ChildItem $old_hintpath.Substring(0, $old_hintpath.IndexOf($package))
    $new_package_dir = $all_packages | ? {$_.Name -like "$package.[0-9.]*"} |
                                       ? {$_.Name -notlike "$package.$old_version"} |
                                       Select -First 1
    $new_version = $new_package_dir | Select-String "$package.([\d\.]+)" |
                                  % {$_.Matches} |
                                  % {$_.Groups[1].Value}

    $dll = Get-ChildItem -Path $new_package_dir.FullName -Recurse -Include *.dll | Select -First 1
    $reference.HintPath = [string](Get-Item $dll.FullName | Resolve-Path -Relative)
    $reference.Include = $reference.Include.Replace("Version=$old_version","Version=$new_version")

    Pop-Location
    $csproj.Save($csproj_path)
}

@Paul Milla 謝謝你在這裡分享你的解決方案。請標記你的答案,這對其他遇到相同問題的社區有益。 - Weiwei
1
警告!这不涉及程序集绑定重定向。如果您的项目存在冲突的传递依赖关系,您仍然需要刷新绑定重定向。https://learn.microsoft.com/zh-cn/dotnet/framework/configure-apps/redirect-assembly-versions - bartonm

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