Visual Studio项目生成引擎-MSBuild构建工具笔记精要

适用语言环境(本文)

CShrp及VB,注意C++环境稍有差异,有关适用于C++的MSBuild的信息,请参阅MSBuild(C++)

概要

Microsoft 生成引擎是一个用于生成应用程序的平台。 此引擎(也称为 MSBuild)为项目文件提供了一个 XML 架构,用于控制生成平台处理和生成软件的方式。 Visual Studio 会使用 MSBuild,但 MSBuild 不依赖于 Visual Studio。 通过在项目或解决方案文件中调用 msbuild.exe 或 dotnet build,可以在未安装 Visual Studio 的环境中安排和生成产品。

Visual Studio 使用 MSBuild 来加载和生成托管项目。 Visual Studio 中的项目文件(.csproj、.vbproj、vcxproj 等)包含 MSBuild XML 代码,当你使用 IDE 来生成项目时,此代码就会运行。 Visual Studio 项目会导入所有必要的设置和生成过程来执行典型的开发工作,但你可以从 Visual Studio 内或通过使用 XML 编辑器对其进行扩展或修改。

一、整体解决方案(.sln)

通过sln为项目整体解决方案,由创建项目时VS自动生成。它管理加载多个项目配置信息:

<!--Example-->
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
<!--当前版本:Visual Sudio 2022 -->
VisualStudioVersion = 17.9.34714.143
<!--最低版本:Visual Sudio 2010 -->
MinimumVisualStudioVersion = 10.0.40219.1
<!-- 等号后面包含[项目名称][项目的相对路径][项目加载生成的GUID] -->
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mes.DataAcquire.WebApi", "Mes.DataAcquire.WebApi\Mes.DataAcquire.WebApi.csproj", "{E18B20D7-AE1F-4647-A335-2E0F68BC04AA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Builds", "Builds", "{844A1604-1155-49A5-8C88-1E76114ED5E2}"
	ProjectSection(SolutionItems) = preProject
        <!-- 自定义全局编译信息 -->
		Directory.Build.props = Directory.Build.props
	EndProjectSection
EndProject
Global
<!-- 省略 -->
EndGlobal

具体请见官方文档:解决方案 (.sln) 文件

1、自定义生成(.props和.targets)

使用标准生成进程(导入 Microsoft.Common.props 和 Microsoft.Common.targets)的 MSBuild 项目有多个可用于自定义生成过程的扩展性挂钩 。

许多可自定义的生成操作由属性控制。 了解如何以及在何处设置属性值以获得所需的效果非常重要。 可以在命令行(和响应文件)、特殊文件(如 Directory.Build.props)、导入的文件或项目文件中设置属性。 了解属性的使用、设置或更改位置以及导入文件的顺序(包括从诸如 .NET SDK 之类的 SDK 隐式导入)非常重要。

有关属性的列表,请参阅 MSBuild 通用属性

选择将属性添加到 .props 或 .targets 文件

MSBuild 依赖于导入顺序,属性(或 UsingTask 或目标)的最后一个定义是使用的定义。
使用显式导入时,可以随时从 .props 或 .targets 文件导入。 下面介绍广泛使用的约定:

  • .props 文件在导入顺序的早期导入。
  • .targets 文件在生成顺序的后期导入。

此约定由 <Project Sdk="SdkName"> 导入强制执行(即,在文件的所有内容之前首先导入 Sdk.props,然后在文件的所有内容之后最后导入 Sdk.targets)。

(1) 用户自定义选项文件(Directory.Build.props)

Directory.Build.props是用户定义的对目录下的项目提供自定义选项的文件 。 除非属性 ImportDirectoryBuildTargets 设为 false,否则该文件将从 Microsoft.Common.targets 自动导入 。

注意:是在任何项目上右键[新键项]才能创建,在解决方案上搜索不出来(我是这样的情况)

名称按右侧描述的文件名直接抄上去就行,添加后IDE自行会在解决方案下创建Builds目录,并生成该文件,同时会在sln解决方案中引用该自定义选项文件。

<!--Example-->
<Project>
	<PropertyGroup>
		<!-- 基础中间件输出路径:默认为[项目根路径\obj] -->
		<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory).vs\$(SolutionName)\Intermediate\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
		<OutputPath>$(MSBuildThisFileDirectory)\OutPut\</OutputPath>
		<AppendTargetFrameworkToOutputPath>True</AppendTargetFrameworkToOutputPath>
	</PropertyGroup>
</Project>
  • $(MSBuildThisFileDirectory):sln解决方案所在的根路径
  • $(SolutionName):sln解决方案所在的目录名
  • $(MSBuildProjectName):当前项目名称(项目文件.csproj的主文件名)

具体请见官方档:MSBuild 保留属性和已知属性

  • AppendTargetFrameworkToOutputPath:是否将目标框架名字对象 (TFM) 追加到输出路径(由 OutputPath 定义)。 .NET SDK 会自动将目标框架以及运行时标识符(如果有)追加到输出路径。
  • AppendRuntimeIdentifierToOutputPath:是否将运行时标识符 (RID) 追加到输出路径。 .NET SDK 会自动将目标框架以及运行时标识符(如果有)追加到输出路径。

具体请见官方档:与发布相关的属性

2、 项目文件(.csproj或.vbproj)

<!--.csproj Example-->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <!-- 输出类型:Windows应用程序-->
    <OutputType>WinExe</OutputType>
    <!--目标框架-->
    <TargetFramework>net6.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
    <!--程序图标-->
    <ApplicationIcon>Theme\Images\App.ico</ApplicationIcon>
  </PropertyGroup>

  <ItemGroup>
    <!-- 排除目录 -->
    <Compile Remove="obj\**" />
    <EmbeddedResource Remove="obj\**" />
    <None Remove="obj\**" />
    <Page Remove="obj\**" />
  </ItemGroup>

  <ItemGroup>
    <!--包引用-->
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.30" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.30" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.3" />
  </ItemGroup>

  <ItemGroup>
    <!--项目引用-->
    <ProjectReference Include="..\Mes.DataAcquire.Entity\Mes.DataAcquire.Entity.csproj" />
  </ItemGroup>

  <ItemGroup>
    <!--资源引用-->
    <Resource Include="Theme\Images\App.ico">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Resource>
    <Resource Include="Theme\Images\icon.png" />
  </ItemGroup>

  <!--预生成事件-->
  <!--<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="echo OutDir: $(OutDir)&#xD;&#xA;echo ProjectDir: $(ProjectDir)&#xD;&#xA;echo TargetPath: $(TargetPath)&#xD;&#xA;echo AssemblyName $(AssemblyName)" />
  </Target>-->

  <!--生成后事件-->
  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <!-- 调用批处理命令-->
    <Exec Command="call &quot;$(ProjectDir)zh-CN_Hans.bat&quot; &quot;$(ProjectDir)$(OutDir)zh-CN&quot;" />
  </Target>
</Project>
(1) 预生成事件

提示:变量值的打印输出,可以通过echo指令进行获得。

(2) 生成后事件
::Example
@echo off
setlocal

::设置源路径和目标路径
set SourcePath=C:\Users\1\source\repos\zh-CN
set TargetPath=%1

::预处理逻辑

endlocal

提示:将MsBuild预置属性变量转入批处理中,再做具体处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值