写点什么

不容错过的 MSBuild 技巧,必备用法详解和实践指南

作者:这我可不懂
  • 2023-08-07
    福建
  • 本文字数:4113 字

    阅读完需:约 13 分钟

不容错过的MSBuild技巧,必备用法详解和实践指南

一、MSBuild 简介


MSBuild 是一种基于 XML 的构建引擎,用于在.NET Framework 和.NET Core 应用程序中自动化构建过程。它是 Visual Studio 的构建引擎,可在命令行或其他构建工具中使用。


MSBuild 使用 XML 文件格式来指定项目的编译、测试和部署等各个阶段的任务。这些 XML 文件通常以.csproj 文件的形式存储。每个项目文件都包含一个或多个 PropertyGroup 元素和一个或多个 ItemGroup 元素。 PropertyGroup 元素声明和定义属性,例如目标框架、输出路径和程序集名称等。 ItemGroup 元素创建项,例如 NuGet 包引用、文件和资源等。


可以使用 dotnet build 命令或 msbuild 命令来运行 MSBuild,它会自动查找与当前目录相关联的项目并执行构建过程。你还可以使用/t 选项指定一个或多个目标,例如 Clean、Build 和 Publish。


MSBuild 支持条件和属性组合,可以为不同的目标平台自定义构建过程。还可以使用自定义任务,例如运行代码静态分析器或压缩构建输出文件等。

二、MSBuild 应用场景


MSBuild 可以用于多种场景,包括:

  • 编译源代码 MSBuild 可以编译应用程序中的源代码文件,将它们编译成二进制文件,以便在部署时使用。它支持多种编译选项,例如优化、生成调试信息和设置警告等级等。

  • 处理配置文件和资源文件 MSBuild 还可以处理应用程序的配置文件和资源文件,例如 App.config 和 Resources.resx 文件。它可以将这些文件复制到应用程序目录中,并将其包含在最终编译的二进制文件中。

  • 安装和注册组件 如果应用程序依赖于其他组件或库,MSBuild 可以自动安装和注册这些组件,以确保应用程序能够正常运行。它也可以从 NuGet 包管理器中下载和安装依赖项。

  • 打包和部署应用程序 MSBuild 可以将应用程序打包成 zip 文件或其他格式,以方便部署到其他环境中。它还可以自动部署应用程序到远程服务器或云平台上,例如 Azure 或 AWS。

  • 自定义任务 除了执行预定义的任务之外,MSBuild 还可以编写自定义任务,以执行特定的构建任务。例如,你可以编写一个任务来执行代码静态分析或压缩构建输出文件。

三、MSBuild 基础知识


以下是一些 MSBuild 基础知识:

属性

属性是声明和定义变量的方式。可以使用 SetProperty 元素或 PropertyGroup 元素来定义属性。例如:

<PropertyGroup>  <MyProperty>MyValue</MyProperty></PropertyGroup>
复制代码

项用于表示一个或多个文件或其他资源。可以使用 ItemGroup 元素和具有 Include 属性的元素来创建项。例如:

<ItemGroup>  <Compile Include="*.cs" /></ItemGroup>
复制代码

任务

任务是执行构建过程中的特定操作的方式。可以使用 Task 元素和具有 TaskName 属性的元素来声明和定义任务。例如:

<TaskName Parameter1="Value1" Parameter2="Value2" />
复制代码

运行构建

要在命令行上运行 MSBuild,请使用以下命令:

msbuild MyProject.csproj /t:Build /p:Configuration=Debug
复制代码

该命令将运行名为 "Build" 的构建目标,并使用名为 "Debug" 的配置文件来构建项目。

四、MSBuild 高级用法


MSBuild 还有许多高级用法,包括:

自定义属性和条件

在项目文件中定义自定义属性和条件,例如定义一个自定义属性来指定构建输出目录:

<Project>  <PropertyGroup>    <OutputDirectory>bin\$(Configuration)\</OutputDirectory>  </PropertyGroup>  ...  <Target Name="Build">    <MakeDir Directories="$(OutputDirectory)" />    ...  </Target></Project>
复制代码

此时,可以在通用属性文件中定义属性值,然后在不同的项目文件中包含该通用属性文件,以便重复使用自定义属性。

目标依赖关系

在项目文件中声明目标之间的依赖关系,例如,在两个目标之间添加依赖关系:

<Project>  ...  <Target Name="Build">    ...  </Target>  <Target Name="Test" DependsOnTargets="Build">    ...  </Target></Project>
复制代码

这样,MSBuild 在执行 "Test" 目标时,会先执行 "Build" 目标。

自定义任务

编写自定义任务来执行构建过程中的特定任务。例如,使用 MSBuildCommunityTasks 执行 FTP 上传:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  <UsingTask TaskName="FTPTask" AssemblyFile="MSBuild.Community.Tasks.dll" />  <Target Name="UploadFile">    <FTPTask ServerHost="ftp.example.com"             RemoteFile="upload.txt"             LocalFile="c:\files\upload.txt"             Username="user"             Password="pass" />  </Target></Project>
复制代码

这个示例中,定义了一个名为 "FTPTask" 的自定义任务,然后在 "UploadFile" 目标中调用该任务来执行 FTP 上传。

条件表达式

使用条件表达式根据条件执行不同的任务。例如,根据平台类型选择不同的构建配置:

<Project>  ...  <Choose>    <When Condition="'$(Platform)' == 'x86'">      <PropertyGroup>        <DefineConstants>DEBUG;X86</DefineConstants>        ...      </PropertyGroup>    </When>    <When Condition="'$(Platform)' == 'x64'">      <PropertyGroup>        <DefineConstants>DEBUG;X64</DefineConstants>        ...      </PropertyGroup>    </When>  </Choose>  ...</Project>
复制代码

此示例使用条件表达式 <Choose> 和 <When> 标记,通过判断 $(Platform) 变量的值来选择执行不同的 PropertyGroup。

自定义构建日志

自定义构建日志以记录构建过程中的详细信息。例如,将构建日志输出到文件:

<Project>  <PropertyGroup>    <LogDirectory>logs\</LogDirectory>  </PropertyGroup>  <Target Name="Build">    <Exec Command="dotnet build MyApp.csproj" />  </Target>  <Target Name="LogBuild" AfterTargets="Build">    <Message Text="Writing build log to $(LogDirectory)\build.log" Importance="high" />    <WriteLinesToFile File="$(LogDirectory)\build.log" Lines="$([System.DateTime]::Now.ToString()) - Build succeeded." />  </Target></Project>
复制代码

此示例中,定义了一个名为 "LogBuild" 的目标,并在执行 "Build" 目标之后调用该目标。在 "LogBuild" 目标中,使用 <Message> 元素将日志输出到控制台,使用 <WriteLinesToFile> 元素将日志写入日志文件。

五、MSBuild 最佳实践


以下是 MSBuild 的一些最佳实践及代码示例:

使用命名属性组,以便更好地组织和管理属性:

<Project>  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">    <DefineConstants>DEBUG;TRACE</DefineConstants>    <Optimize>false</Optimize>    <OutputPath>bin\Debug\</OutputPath>    ...  </PropertyGroup>  ...</Project>
复制代码

在这个示例中,属性都被包含在一个名为 "Debug|AnyCPU" 的 PropertyGroup 中。这样可以更好地组织和管理属性,并且可以使用条件表达式来根据需要选择不同的属性组。

避免硬编码文件路径,而是使用相对路径和通用属性:

<Project>  <ItemGroup>    <Compile Include="src\**\*.cs" />    ...  </ItemGroup>  <PropertyGroup>    <OutputPath>bin\$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Build.props)\)</OutputPath>  </PropertyGroup>  ...</Project>
复制代码

在这个示例中,使用相对路径 "src***.cs" 来指定需要编译的源代码文件,并使用通用属性来获取输出路径,以避免硬编码路径并提高可移植性。

使用预定义的 MSBuild 目标和任务,以便重复使用现有功能:

<Project>  ...  <Target Name="Clean">    <MSBuild Projects="$(MSBuildThisFileFullPath)"             Targets="CleanSolution"             Properties="Configuration=$(Configuration)" />  </Target>  ...</Project>
复制代码

在这个示例中,使用现有的 MSBuild 目标和任务来执行 "Clean" 目标。这样可以重复使用现有功能并提高构建效率。

使用条件表达式来支持多个版本和平台:

<Project>  ...  <Choose>    <When Condition="'$(TargetFramework)' == 'netcoreapp3.1'">      <PropertyGroup>        <DefineConstants>NET_CORE_3_1</DefineConstants>        ...      </PropertyGroup>    </When>    <When Condition="'$(TargetFramework)' == 'net5.0'">      <PropertyGroup>        <DefineConstants>NET_5_0</DefineConstants>        ...      </PropertyGroup>    </When>  </Choose>  ...</Project>
复制代码

在这个示例中,使用条件表达式根据目标框架选择执行不同的操作。这样可以更好地支持多个版本和平台,并保持代码的简洁和易于维护。

禁用 Visual Studio 的自动格式化选项,以避免与代码格式化工具冲突:

<Project>  ...  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">    <EnableEditorConfig>false</EnableEditorConfig>  </PropertyGroup>  ...</Project>
复制代码

在这个示例中,使用 EnableEditorConfig 属性来禁用 Visual Studio 的自动格式化选项,以避免与代码格式化工具冲突。这样可以保持代码格式化的一致性,减少错误和不必要的麻烦。

最后,推荐一款应用开发神器


扯个嗓子!关于目前低代码在技术领域很活跃!


低代码是什么?一组数字技术工具平台,能基于图形化拖拽、参数化配置等更为高效的方式,实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题,是数字化转型过程中降本增效趋势下的产物。


这边介绍一款好用的低代码平台——JNPF 快速开发平台。近年在市场表现和产品竞争力方面表现较为突出,采用的是最新主流前后分离框架(SpringBoot+Mybatis-plus+Ant-Design+Vue3)。代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发。


以 JNPF 为代表的企业级低代码平台为了支撑更高技术要求的应用开发,从数据库建模、Web API 构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动,还没有了解过低代码的伙伴可以尝试了解一下。


应用:https://www.jnpfsoft.com/?infoq

有了它,开发人员在开发过程中就可以轻松上手,充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说,有着很大帮助。

发布于: 21 小时前阅读数: 17
用户头像

低代码技术追随者,为全民开发而努力 2023-02-15 加入

大家好,我是老王,专注于分享低代码图文知识,感兴趣的伙伴就请关注我吧!

评论

发布
暂无评论
不容错过的MSBuild技巧,必备用法详解和实践指南_自动化构建工具_这我可不懂_InfoQ写作社区