[英]How to get a list of nuget packages installed via MSBuild macro?
从以下问题如何列出所有已安装的 NuGet 包?
我需要从 MSBuild 本身获取 nuget 包列表。
我尝试做的事情:
<Target Name="test" AfterTargets="ResolveReferences">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths)"/>
</ItemGroup>
<Message Text="Files @(BuildOutputInPackage -> '%(identity)', ', ')" Importance="high"/>
</Target>
上面的代码返回所有引用,无论它的 nuget 还是项目引用 dll。 如何准确返回当前项目 *.csproj 使用的 nuget 包列表?
格式即: packageid:Portable.BouncyCastle version = "1.9.0"
我使用旧的经典非 sdk csproj 模板和 .NET 4.8 和<PackageReference> not packages.config files.
阅读 *.csproj 并执行正则表达式以获取 <packageReferences 列表非常糟糕。 也许有一个推荐的 MSBuild 宏来执行此操作,如 <Target....
ReferenceCopyLocalPaths
只是“应复制到本地目录的文件的路径”。 并非所有已解析的引用。
是的,不要正则表达式项目文件。 没有必要。 PackageReference
是一个 ItemGroup。
<Target Name="DisplayPackageReference">
<Message Text="@(PackageReference ->'packageid:%(identity) version = "%(version)"', '%0d%0a')" />
</Target>
但请注意, PackageReference
是项目所要求的,并且版本可以是浮动的,例如Version="3.6.*"
。 PackageReference
不会为您提供包引用解析到的包版本。
如果您需要知道使用的具体版本,那么您可能需要安装dotnet
,使用exec
任务运行dotnet list "$(MSBuildProjectFile)" package
,并解析命令的输出。
非常感谢Jonathan Dodds的上述回答。 我将一些方法与他的@(PackageReference)
想法相结合,以在旧的经典 csproj 模板中获取当前引用的 nuget 包的一个版本。 因为引用的版本不能仅与@(PackageReference) only
。 dotnet list 在旧的经典 csproj 模板(非 sdk)中也不能很好地工作。
下面的代码执行以下操作:
(注意这种方法不是 100% 有机的,MSBuild 应该为此提供一个简单的目标):
@(PackageReference)
中的引用。 乔纳森·杜兹 (Jonathan Doods)走近上方。nuget.exe pack ProjectPath.csproj
一个ProjectName.nupkg nuget 将生成。在 Directory.Build.targets 或 .csproj 文件中使用此代码。
<Target Name="GenerateNuspecFile" AfterTargets="AfterBuild">
<ItemGroup>
<!-- Get all references -->
<MyReference Include="@(ReferenceCopyLocalPaths)" Condition="%(extension) == '.dll'">
<FirstDir>$([System.IO.Directory]::GetParent(%(RelativeDir)))</FirstDir>
<LibDir>$([System.IO.Path]::GetFileNameWithoutExtension(%(MyReference.FirstDir)))</LibDir>
<SecondDir>$(FirstDir)</SecondDir>
<SecondDir Condition="$(LibDir) != 'lib'">$([System.IO.Directory]::GetParent(%(MyReference.FirstDir)))</SecondDir>
<VersionDir>$([System.IO.Directory]::GetParent(%(MyReference.SecondDir)))</VersionDir>
<PackageDir>$([System.IO.Directory]::GetParent(%(MyReference.VersionDir)))</PackageDir>
<PackageID>$([System.IO.Path]::GetFileName(%(MyReference.PackageDir)))</PackageID>
</MyReference>
<!-- Get Non nuget references -->
<ExcludedReference Condition="@(MyReference) != ''" Include="@(MyReference -> '%(PackageID)')" Exclude="@(PackageReference -> '%(identity)')"/>
<!-- Exclude Non nuget references. The remain will be nuget references -->
<MyPackage Condition="@(MyReference) != ''" Include="@(MyReference -> '%(PackageID)')" Exclude="@(ExcludedReference -> '%(identity)')"/>
<!-- Get Nuspec File -->
<NuspecFile Condition="@(MyPackage) != ''" Include="%(MyPackage.VersionDir)\**\*.nuspec"/>
<!-- Read Nuspec File -->
<NuspecContent Condition="@(NuspecFile) != ''" Include="@(NuspecFile)">
<Content>$([System.IO.File]::ReadAllText(%(fullpath)))</Content>
<PackageIDRegex><id>(.*?)</id></PackageIDRegex>
<PackageID>$([System.Text.RegularExpressions.Regex]::Match('%(NuspecContent.Content)', '%(NuspecContent.PackageIDRegex)' ))</PackageID>
<PackageID>$([System.String]::Copy('%(NuspecContent.PackageID)').Replace('<id>','').Replace('</id>', '').Trim())</PackageID>
<VersionRegex><version>(.*?)</version></VersionRegex>
<Version>$([System.Text.RegularExpressions.Regex]::Match('%(NuspecContent.Content)', '%(NuspecContent.VersionRegex)' ))</Version>
<Version>$([System.String]::Copy('%(NuspecContent.Version)').Replace('<version>','').Replace('</version>', '').Trim())</Version>
</NuspecContent>
</ItemGroup>
<!-- Generate Nuspec File with dependencies-->
<PropertyGroup>
<NewLine>%0d%0a</NewLine>
<Space2>%20%20</Space2>
<Space4>$(Space2)$(Space2)</Space4>
<Space6>$(Space4)$(Space2)</Space6>
<HasDependencies>false</HasDependencies>
<HasDependencies Condition="@(MyPackage) != ''">true</HasDependencies>
<Nuspec>$(Nuspec)<?xml version="1.0" encoding="utf-8"?>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)<package >$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)<metadata>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<id>$id$</id>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<version>$version$</version>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<title>$title$</title>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<authors>$author$</authors>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<owners>$author$</owners>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<requireLicenseAcceptance>false</requireLicenseAcceptance>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<licenseUrl>https://company.com</licenseUrl>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<icon>PackageIcon.png</icon>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<projectUrl>http://company.com</projectUrl>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<description>$description$</description>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<releaseNotes>$description$</releaseNotes>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<copyright>$copyright$</copyright>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<tags>$title$ company company.com</tags>$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)$(Space4)<dependencies>$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)@(NuspecContent -> '$(Space6)<dependency id="%(PackageID)" version="%(Version)"/>', '$(NewLine)')$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)$(Space4)</dependencies>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)</metadata>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)<files>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<file src="..\**\PackageIcon.png"/>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)</files>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)</package>$(NewLine)</Nuspec>
</PropertyGroup>
<WriteLinesToFile Lines="$(Nuspec)" File="$(MSBuildProjectDirectory)\$(MSBuildProjectName).nuspec" Overwrite="true"/>
</Target>
生成的.nuspec
文件将是:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<licenseUrl>https://company.com</licenseUrl>
<icon>PackageIcon.png</icon>
<projectUrl>http://company.com</projectUrl>
<description>$description$</description>
<releaseNotes>$description$</releaseNotes>
<copyright>$copyright$</copyright>
<tags>$title$ company company.com</tags>
<dependencies>
<dependency id="Company.Globals" version="2022.7.19"/>
<dependency id="Portable.BouncyCastle" version="1.9.0"/>
</dependencies>
</metadata>
<files>
<file src="..\**\PackageIcon.png"/>
</files>
</package>
使用 MSBuild 真的很难实现任何目标。 也许您可以为此创建一个控制台应用程序,然后直接使用<Exec Command =""/>
调用控制台应用程序。 但是目前的方法对 MSBuild 很友好。 它不是 100% 有机的方法。 MSBuild 应该为我们提供一个目标,以获取具有引用版本的引用 nuget 包。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.