如何在SDK项目的预构建阶段运行dotnet工具
问题描述
我希望在构建流程的编译环节前运行dotnet工具,已在SDK项目文件中添加如下配置:
<ItemGroup> <PackageDownload Include="MyTool" Version="[1.0.1]" /> </ItemGroup>
工具会被下载至路径:
\Users\me\.nuget\packages\MyTool\1.0.1\tools\netcoreapp3.1\any\
随后添加了预构建目标:
<Target Name="PreBuild" BeforeTargets="CoreCompile"> <Exec Command="dotnet C:\Users\me\.nuget\packages\MyTool\1.0.1\tools\netcoreapp3.1\any\MyTool.dll <MyOptions>" /> </Target>
该方案可正常运行,但不想在路径中使用用户目录或版本号的绝对引用。尝试为PackageDownload添加GeneratePathProperty="true",但$(PkgMyTool)未定义;使用<PackageReference>引用工具时,因SDK不兼容失败(工具为netcore3.1,项目为netstandard2.0)。
解决方案
方法1:用NuGet内置变量+版本属性简化路径
可以通过$(NuGetPackageRoot)获取NuGet包的根目录,同时把工具版本单独定义成属性,避免硬编码:
<!-- 先定义工具版本属性,后续只需改这里 --> <PropertyGroup> <MyToolVersion>1.0.1</MyToolVersion> </PropertyGroup> <ItemGroup> <PackageDownload Include="MyTool" Version="[$(MyToolVersion)]" /> </ItemGroup> <Target Name="PreBuild" BeforeTargets="CoreCompile"> <Exec Command="dotnet $(NuGetPackageRoot)MyTool\$(MyToolVersion)\tools\netcoreapp3.1\any\MyTool.dll <MyOptions>" /> </Target>
$(NuGetPackageRoot)会自动适配不同系统的NuGet存储路径,不用手动写用户目录,版本号也只需要维护一处。
方法2:用MSBuild任务动态获取工具路径
如果不想硬编码版本号,可以用GetPackageDownloads任务自动获取已下载包的路径:
<ItemGroup> <PackageDownload Include="MyTool" Version="[1.0.1]" /> </ItemGroup> <Target Name="PreBuild" BeforeTargets="CoreCompile"> <GetPackageDownloads PackageDownloads="@(PackageDownload)"> <Output TaskParameter="PackageDownloadPaths" ItemName="MyToolPath" /> </GetPackageDownloads> <!-- 拼接工具DLL的完整路径 --> <Exec Command="dotnet %(MyToolPath.FullPath)tools/netcoreapp3.1/any/MyTool.dll <MyOptions>" /> </Target>
这个任务会返回PackageDownload中包的实际存储根路径,完全不用写死用户目录和版本号,适配性更强。
方法3:用DotNetToolReference(推荐)
虽然PackageReference因框架兼容失败,但可以用专门的<DotNetToolReference>引用.NET工具,它不会受项目目标框架的影响:
<ItemGroup> <DotNetToolReference Include="MyTool" Version="1.0.1" /> </ItemGroup> <Target Name="PreBuild" BeforeTargets="CoreCompile"> <!-- 直接调用工具名,无需关心路径 --> <Exec Command="dotnet mytool <MyOptions>" /> </Target>
用这种方式的话,MSBuild会自动处理工具的下载和路径映射,你只需要直接通过dotnet mytool调用即可,是最简洁的方案(前提是你的MyTool是符合.NET工具规范的包)。
内容的提问来源于stack exchange,提问作者TheRoadrunner
相关产品推荐
相关产品推荐

