乘风破浪,遇见最美Windows 11之现代Windows桌面应用开发 - 自定义生成配置文件(Directory.Build.props)来实现灵活切换
背景
有时候我们在同一套代码基础上,我们存在多种商业/渠道/品牌,如果写死在代码里面,每次调试、打包可能需要改代码才行,那么有没有办法实现动态的输入呢?我们可以利用MsBuild的一个高级特性,自定义生成配置来实现这个需求。

工作原理
通过在包含源的根文件夹中名为Directory.Build.props的单个文件内定义一个新属性,可以向每个项目添加该属性。在MSBuild运行时,Microsoft.Common.props会搜索Directory.Build.props文件的目录结构(Microsoft.Common.targets将查找Directory.Build.targets)。如果找到了一个文件,它将导入该文件并读取其中定义的属性。
Directory.Build.props是用户定义文件,对目录下的项目提供自定义选项。
直白一点说:只要你的项目根目录或者父级目录存在一个自定义的
Directory.Build.props,你的Visual Studio就会把它读取到可视化操作面板的配置清单中来,你就可以自由切换了。
自定义配置文件位置
这个很有意思,实际上自定义的Directory.Build.props文件的位置很灵活,它可以位于项目的根目录,也可以父级,再父级,MsBuild会从你的项目目录往上一直找,找到为止,如果没找到就算了,找到了就用起来,但是需要注意,这个文件的名称必须完全是:Directory.Build.props,大小写都不能偏差,在这个基础上,也能保障Linux下也可以用。
举个例子,如果你的项目位置是:c:\users\username\code\test\case1,MsBuild会先往上一级目录开始找,比如c:\users\username\code\test,找到就用,找不到继续往上一级目录c:\users\username\code找,依此类推,找到或找不到为止。
另外,解决方案文件(.sln)所在位置和Directory.Build.props所在位置没有关系,只和项目的位置有关系。
勤学实战
创建解决方案HelloDesktopBuildConfig
dotnet new sln -o HelloDesktopBuildConfig
cd .\HelloDesktopBuildConfig\
explorer.exe .

创建.Net Framework项目demoForNetFramework

选择C#语言-Windows平台-桌面类型,选中Windows窗体应用(.Net Framework)模板,创建名为demoForNetFramework2.0的项目。



先试试从Visual Studio创建配置
- 进入配置管理器

- 新建配置

- 新建解决方案配置
这里我们可以选择从已有的两个配置进行复制,比如这里我从Debug配置进行复制创建,起名为LinuxDebug

这样一个名为LinuxDebug的配置就快速创建好了。


- 查看新建配置
我们来看看这个从Visual Studio内部创建的配置是咋回事。
我们看到,demoForNetFramework2.0.csproj这个文件内容发生了变化。

在这个文件的Project节点下新建了一个PropertyGroup节点,其内容是:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'LinuxDebug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\LinuxDebug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
在这个前面我们还看到已存在的另外两个配置:Debug、Release,还有个没有条件的。
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{08A34EAE-7E05-4293-A6D8-135DD99CB485}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>demoForNetFramework2._0</RootNamespace>
<AssemblyName>demoForNetFramework2.0</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
配置内容解读
目标平台(PlatformTarget)
目标平台是指将在其上运行生成项目的特定平台。
AnyCPU应该是指代全部。x86指定在Intel 80x86处理器或等效处理器上运行的32位Windows操作系统。x64指定在Intel x64处理器或等效处理器上运行的64位Windows操作系统。Xbox指定Microsoft Xbox 360平台
语言版本控制(LangVersion)
默认值:
| 目标框架 | version | C# 语言版本的默认值 |
|---|---|---|
| .NET | 6.x | C# 10 |
| .NET | 5.x | C# 9.0 |
| .NET Core | 3.x | C# 8.0 |
| .NET Core | 2.x | C# 7.3 |
| .NET Standard | 2.1 | C# 8.0 |
| .NET Standard | 2.0 | C# 7.3 |
| .NET Standard | 1.x | C# 7.3 |
| .NET Framework | 全部 | C# 7.3 |
版本清单:
| 值 | 含义 |
|---|---|
| preview | 编译器接受最新预览版中的所有有效语言语法。 |
| latest | 编译器接受最新发布的编译器版本(包括次要版本)中的语法。 |
| latestMajor (default) | 编译器接受最新发布的编译器主要版本中的语法。 |
| 10.0 | 编译器只接受 C# 10 或更低版本中所含的语法。 |
| 9.0 | 编译器只接受 C# 9 或更低版本中所含的语法。 |
| 8.0 | 编译器只接受 C# 8.0 或更低版本中所含的语法。 |
| 7.3 | 编译器只接受 C# 7.3 或更低版本中所含的语法。 |
| 7.2 | 编译器只接受 C# 7.2 或更低版本中所含的语法。 |
| 7.1 | 编译器只接受 C# 7.1 或更低版本中所含的语法。 |
| 7 | 编译器只接受 C# 7.0 或更低版本中所含的语法。 |
| 6 | 编译器只接受 C# 6.0 或更低版本中所含的语法。 |
| 5 | 编译器只接受 C# 5.0 或更低版本中所含的语法。 |
| 4 | 编译器只接受 C# 4.0 或更低版本中所含的语法。 |
| 3 | 编译器只接受 C# 3.0 或更低版本中所含的语法。 |
| ISO-2(或 2) | 编译器只接受 ISO/IEC 23270:2006 C# (2.0) 中所含的语法。 |
| ISO-1(或 1) | 编译器只接受 ISO/IEC 23270:2003 C# (1.0/1.2) 中所含的语法。 |

浙公网安备 33010602011771号