[英]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.