我有一个 powershell 脚本,可以从 Visual Studio 中的包管理器控制台启动。 特别是我有一个与此命令相关的问题:
Update-Package -ProjectName $ProjectName -reinstall
此命令将来自
packages.config
(我主要使用旧版非 sdk 项目)的包安装到指定项目中。
当我对当前打开的解决方案中的项目运行此命令时,一切都很好。但我不想打开许多解决方案来更新包,而是编写了一个脚本(在 VS 中称为内部包管理器),该脚本只是进入特定的解决方案文件夹并在那里更新项目。它可以工作,但 .csproj 文件中
packages
文件夹的生成路径是相对于最初打开的解决方案创建的,而不是相对于特定项目所属的解决方案。这导致路径如下:
..\..\..\..\SomeNotCurrentlyOpenedSolution\packages\..
只是
..\packages\..
有办法解决吗?也许可以以某种方式强制 VS 认为针对指定解决方案启动特定命令,而不是当前始终打开
更新1: 请参阅命令日志和说明:
为了说明这个问题,我有 2 个新创建的空解决方案:
ClassLibrary1.sln
和 ClassLibrary2.sln
。 ClassLibrary1.csproj
(解决方案内的单个项目)有关于 newtonsoft
包的参考。我已在 Package Manager Console
中打开 ClassLibrary2.sln
并输入以下命令:
PM> ls
Directory: C:\test\ClassLibrary2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/9/2024 9:53 PM ClassLibrary2
-a---- 3/9/2024 9:53 PM 1145 ClassLibrary2.sln
PM> Get-Content ..\ClassLibrary1\ClassLibrary1\ClassLibrary1.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
...
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
...
正如我们所看到的,
ClassLibrary1.csproj
有对Newtonesoft.Json
包的引用以及预期的路径。
按照@jdweng的建议,我已经
cd
编入ClassLibrary1.csproj
。
PM> cd ..\ClassLibrary1\ClassLibrary1
PM> ls
Directory: C:\test\ClassLibrary1\ClassLibrary1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/9/2024 9:28 PM bin
d----- 3/9/2024 9:28 PM obj
d----- 3/9/2024 9:28 PM Properties
-a---- 3/9/2024 9:28 PM 196 Class1.cs
-a---- 3/9/2024 9:30 PM 2528 ClassLibrary1.csproj
-a---- 3/9/2024 9:30 PM 144 packages.config
并尝试更新
ClassLibrary1.csproj
中的软件包。直到我将 ClassLibrary1.csproj
项目添加到 ClassLibrary2
解决方案中(这对我来说很好),它才起作用。
PM> Update-Package -ProjectName ClassLibrary1 -reinstall
Update-Package : Project 'ClassLibrary1' is not found.
At line:1 char:1
+ Update-Package -ProjectName ClassLibrary1 -reinstall
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (ClassLibrary1:String) [Update-Package], ItemNotFoundException
+ FullyQualifiedErrorId : NuGetProjectNotFound,NuGet.PackageManagement.PowerShellCmdlets.UpdatePackageCommand
将ClassLibrary1.csproj项目添加到ClassLibrary2解决方案中后,命令已成功:
PM> ls
Directory: C:\test\ClassLibrary1\ClassLibrary1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/9/2024 10:02 PM bin
d----- 3/9/2024 9:28 PM obj
d----- 3/9/2024 9:28 PM Properties
-a---- 3/9/2024 9:28 PM 196 Class1.cs
-a---- 3/9/2024 10:12 PM 2278 ClassLibrary1.csproj
-a---- 3/9/2024 10:12 PM 144 packages.config
PM> Update-Package -ProjectName ClassLibrary1 -reinstall
Attempting to gather dependency information for multiple packages with respect to project 'ClassLibrary1', targeting '.NETFramework,Version=v4.5.2'
Gathering dependency information took 216 ms
Attempting to resolve dependencies for multiple packages.
Resolving dependency information took 0 ms
Resolving actions install multiple packages
Retrieving package 'Newtonsoft.Json 13.0.3' from 'nuget.org'.
Removed package 'Newtonsoft.Json 13.0.3' from 'packages.config'
Successfully uninstalled 'Newtonsoft.Json 13.0.3' from ClassLibrary1
Package 'Newtonsoft.Json.13.0.3' already exists in folder 'C:\test\ClassLibrary2\packages'
Added package 'Newtonsoft.Json.13.0.3' to 'packages.config'
Successfully installed 'Newtonsoft.Json 13.0.3' to ClassLibrary1
Executing nuget actions took 718 ms
Time Elapsed: 00:00:00.9501830
PM> Get-Content .\ClassLibrary1.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\ClassLibrary2\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
您可能会看到
Newtonsoft.Json
二进制文件的路径已更改。我该如何预防?
对于上下文,我想要做的是将
packages.config
中提到的软件包安装到项目文件中。
中的
Update-Package
命令在 Visual Studio 中当前加载的解决方案的上下文中运行。当您从另一个解决方案添加项目并更新其包时,NuGet 会根据当前解决方案的目录解析路径,这会导致您观察到的意外路径更改。
不幸的是,直接从包管理器控制台中操作解决方案上下文以欺骗 Visual Studio 认为已在命令范围内加载不同的解决方案并不简单,也不受现有 NuGet PowerShell 命令支持。
这意味着您必须考虑使用 NuGet 命令行界面 (CLI) 或 MSBuild 自动执行包更新作为替代方案。这两个工具都可以在 Visual Studio 之外使用,并允许您显式指定解决方案或项目文件。这将使您能够更好地控制流程,并避免 Visual Studio 的包管理器控制台出现上下文问题。 例如,使用 NuGet CLI,您可以恢复特定解决方案或项目文件的包,而无需在 Visual Studio 中打开它:
nuget restore YourSolution.sln
或者更新项目的包:
nuget update YourProject.csproj
HintPath
.csproj
。虽然不理想,但这将允许您更正路径,而无需手动编辑每个文件。您可以编写一个 PowerShell 脚本来搜索并替换项目文件中不正确的路径段。
Get-ChildItem -Recurse -Filter *.csproj | ForEach-Object {
(Get-Content $_.FullName).replace('..\..\ClassLibrary2\packages', '..\packages') | Set-Content $_.FullName
}
该脚本会查找所有
.csproj
文件,读取其内容,用正确的相对路径替换不正确的相对路径,然后保存文件。