Bootstrap

csproj内容解析


使用C#很长时间都没太关注,最近查看一些开源软件,有时候需要在csproj更改项目的配置信息,不得不熟悉里面的配置内容。

如果只是想了解csproj文件的配置项的含义,不太关注配置内容的细节,可以查看理解 C# 项目 csproj 文件格式的本质和编译流程。文中介绍了新旧csproj的项目模式元素、区别和编译流程。但是没对每个项目项的属性进行讲解,本文是在该文章的基础上,讲解新csproj文件的项目属性含义。

指定目标框架

指定单个目标框架,使用TargetFramework元素。以下控制台应用程序项目文件演示了如何创建.NET Core 3.0目标框架:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>
</Project>

指定多个目标框架

当指定多个目标框架时,TargetFramework更改为复数TargetFrameworks

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
  </PropertyGroup>
</Project>

在您的库或应用程序中,可以根据编写条件代码以针对每个目标框架进行编译:

public class MyClass
{
    static void Main()
    {
#if NET40
        Console.WriteLine("Target framework: .NET Framework 4.0");
#elif NET45  
        Console.WriteLine("Target framework: .NET Framework 4.5");
#else
        Console.WriteLine("Target framework: .NET Standard 1.4");
#endif
    }
}

.NET Core目标框架的预处理器符号的完整列表为:

目标框架符号
.NET FrameworkNETFRAMEWORK,NET20,NET35,NET40,NET45,NET451,NET452,NET46,NET461,NET462,NET47,NET471,NET472,NET48
.NET StandardNETSTANDARD,NETSTANDARD1_0,NETSTANDARD1_1,NETSTANDARD1_2,NETSTANDARD1_3,NETSTANDARD1_4,NETSTANDARD1_5,NETSTANDARD1_6,NETSTANDARD2_0,NETSTANDARD2_1
.NET CoreNETCOREAPP,NETCOREAPP1_0,NETCOREAPP1_1,NETCOREAPP2_0,NETCOREAPP2_1,NETCOREAPP2_2,NETCOREAPP3_0

系统可识别的预处理符号更改项目目标框架符号时,只需要用.替代_,并将大写字母转换为小写字母(例如,netstandard1.4 的符号是 NETSTANDARD1_4)。详细信息查看Target frameworks

新增其它项目属性

除了上述的默认项目属性,我们还可以添加其他的项目属性,常见的项目属性如下:

  • GeneratePackageOnBuild
    默认为false,如果更改为true,在生成项目时,visual studio将创建的类库生成NuGet包。
  • AssemblyName
    程序集名称。
  • RootNamespace
    默认命名空间
  • OutputType
    输出类型,主要有WinExe、Exe、Library等。
  • PackageId
    NuGet包名称。
  • Authors
    软件作者名。
  • Company
    公司名称。
  • Product
    产品名称。
  • Copyright
    版权信息
  • Description
    对类库的描述和介绍信息。
  • Version
    版本号
  • RepositoryType
    仓库类型
  • PackageTags
    NuGet包标签

相关示例内容如下:

<Project Sdk="Microsoft.NET.Sdk">
  项目中可能有零个或零个以上的 PropertyGroup 元素。-->
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>   
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>   
    <AssemblyName>MyNewStandardSample</AssemblyName>
    <RootNamespace>StandardSample</RootNamespace>
    <OutputType>Library</OutputType>

    <!-- NuGet -->
    <PackageId>MyNewStandardSample</PackageId>
    <Authors>sgmcumt</Authors>
    <Company>gumen</Company>
    <Copyright>company</Copyright>
    <Product>hello world</Product>
    <Description>这是一个测试程序</Description>
    <Version>1.0.1</Version>
    <RepositoryType>git</RepositoryType>
    <PackageTags>test;standard</PackageTags>
  </PropertyGroup>
</Project>

在visual studio中通过选中项目名称–>右键属性,然后更改相关内容,对比在PropertyGroup中的变化。

项目引用

普通NuGet包引用

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

在上面的示例中,12.0.2表示> = 12.0.2的任何版本,并且优先选择最低版本。

在引用包依赖项时,NuGet支持使用区间符号来指定版本范围,总结如下:

符号使用规则描述
1.0x ≥ 1.0最低版本(包含)
(1.0,)x > 1.0最低版本(不包含)
[1.0]x == 1.0完全匹配的版本
(,1.0]x ≤ 1.0最高版本(包含)
(,1.0)x < 1.0最高版本(不包含)
[1.0,2.0]1.0 ≤ x ≤ 2.0版本范围(包含两端版本号)
(1.0,2.0)1.0 < x < 2.0版本范围(不包含两端版本号)
[1.0,2.0)1.0 ≤ x < 2.0版本范围(包含最低版本,不包含最高版本)
(1.0)无效无效

在使用PackageReference格式时,NuGet还支持使用通配符*表示数字的主、次、补丁和预发布后缀部分。packages.config格式文件不支持通配符*,参照Package versioning

添加引用NuGet包的条件

我们在开发可能会遇到这种问题,需要根据要构建的目标框架引用不同的程序集或NuGet程序包,可以在PackageReference上添加条件,来达到该目的。

<ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" Condition="'$(TargetFramework)' == 'net452'" />
</ItemGroup>

条件也可以在该ItemGroup级别上应用,并将适用于所有子PackageReference元素:

<ItemGroup Condition = "'$(TargetFramework)' == 'net452'">
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
    <PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup>

如果是要根据多个条件引用NuGet程序包,如何实现了?
在这里展示如何使用多个条件,因此无论我们是针对.NET 4.6.2还是3.5,我们都将引用它:

<ItemGroup Condition=" '$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net35'">
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

更多信息,详细查看Package references (PackageReference) in project files

托管程序集引用

在使用.net framework框架时,需要添加一些程序集,例如在.NET 4.6.2目标中添加System.Web程序集的引用

<ItemGroup Condition=" '$(TargetFramework)' == 'net462' ">
    <Reference Include="System.Web" />
</ItemGroup>
项目元数据名称描述
HintPath可选字符串。程序集的相对或绝对路径。
Name可选字符串。程序集的显示名称,例如“ System.Windows.Forms”。
FusionName可选字符串。指定项目的简单或强融合名称。如果存在此属性,则可以节省时间,因为不必打开程序集文件即可获取融合名称。
SpecificVersion可选布尔值。指定是否仅应引用融合名称中的版本。
Aliases可选字符串。可供参考的名称。
Private可选布尔值。指定是否将引用复制到输出文件夹。此属性与Visual Studio IDE中引用的“ 复制本地”属性匹配。

添加COM组件引用

<ItemGroup>
    <COMReference Include="Acrobat.dll">
        <Guid>78165d71-df28-11d3-9a89-005004a56d53</Guid>
        <VersionMajor>1</VersionMajor>
        <VersionMinor>0</VersionMinor>
        <WrapperTool>tlbimp</WrapperTool>
        <Lcid>0</Lcid>
        <Isolated>false</Isolated>
    </COMReference>
</ItemGroup>

COMReference表示项目中的COM(非托管)组件引用。此项仅适用于.NET项目。

项目元数据名称描述
Name可选字符串。组件的显示名称。
Guid必需的字符串。组件的GUID,格式为{78165d71-df28-11d3-9a89-005004a56d53}。
VersionMajor必需的字符串。组件版本号的主要部分。例如,如果完整版本号为“ 5.46”,则为“ 5”。
VersionMinor必需的字符串。组件版本号的一小部分。例如,如果完整版本号为“ 5.46”,则为“ 46”。
LCID可选字符串。组件的LocaleID。
WrapperTool可选字符串。组件上使用的包装工具的名称,例如“ tlbimp”。
Isolated可选布尔值。指定该组件是否为免注册组件。

本机文件引用

NativeReference表示对本机清单文件或此类文件的引用。

项目元数据名称描述
Name必需的字符串。清单文件的基本名称。
HintPath必需的字符串。清单文件的相对路径。

项目引用

ProjectReference表示对另一个项目的引用。

<ItemGroup>
  <ProjectReference Include="..\Data.csproj">
    <Project>{fa2f8c34-679a-4d47-adcc-375015354dd7}</Project>
    <Name>Data</Name>
  </ProjectReference>
</ItemGroup>
项目元数据名称描述
Name可选字符串。引用的显示名称。
Project可选字符串。供参考的GUID,格式为{12345678-1234-1234-1234-1234567891234}。
Package可选字符串。被引用的项目文件的路径。
ReferenceOutputAssembly可选布尔值。如果设置为false,则不包括被引用项目的输出作为该项目的引用,但仍确保另一个项目在此项目之前构建。默认为true。

编译

Compile表示生成项目时要编译的源文件。

<ItemGroup>
  <Compile Include="Program.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
  <Compile Include="Properties\Resources.Designer.cs">
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>Resources.resx</DependentUpon>
  </Compile>
</ItemGroup>
项目元数据名称描述
DependentUpon可选字符串。指定此文件正确编译所依赖的文件。
AutoGen可选布尔值。指示文件是否由Visual Studio集成开发环境(IDE)生成的。
Link可选字符串。当文件实际位于项目文件的影响范围之外时要显示的符号路径。
Visible可选布尔值。指示是否在Visual Studio的解决方案资源管理器中显示文件。
CopyToOutputDirectory可选字符串。确定是否将文件复制到输出目录。值包括:1.Never 2.Always 3. PreserveNewest

嵌入式资源

EmbeddedResource表示要嵌入到生成的程序集中的资源。

<ItemGroup>
  <EmbeddedResource Include="Properties\Resources.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    <SubType>Designer</SubType>
  </EmbeddedResource>
</ItemGroup>
项目元数据名称描述
DependentUpon可选字符串。指定该文件正确编译所依赖的文件
Generator必需的字符串。在此项目上运行的任何文件生成器的名称。
LastGenOutput必需的字符串。由此项上运行的任何文件生成器创建的文件名。
CustomToolNamespace必需的字符串。在此项目上运行的任何文件生成器都应在其中创建代码的名称空间。
Link可选字符串。如果文件实际位于项目影响范围之外,则会显示符号路径。
Visible可选布尔值。指示是否在Visual Studio的解决方案资源管理器中显示文件。
CopyToOutputDirectory可选字符串。确定是否将文件复制到输出目录。值包括:1.Never 2.Always 3. PreserveNewest
LogicalName必需的字符串。嵌入式资源的逻辑名称。

None

None表示在构建过程中不应该起作用的文件。

<ItemGroup>
  <None Include="App.config">
    <SubType>Designer</SubType>
  </None>
  <None Include="packages.config" />
</ItemGroup>

输入

表示其名称空间应由Visual Basic编译器导入的程序集。

其它

更多项目项请查看Common MSBuild project items

;