使用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 Framework | NETFRAMEWORK,NET20,NET35,NET40,NET45,NET451,NET452,NET46,NET461,NET462,NET47,NET471,NET472,NET48 |
.NET Standard | NETSTANDARD,NETSTANDARD1_0,NETSTANDARD1_1,NETSTANDARD1_2,NETSTANDARD1_3,NETSTANDARD1_4,NETSTANDARD1_5,NETSTANDARD1_6,NETSTANDARD2_0,NETSTANDARD2_1 |
.NET Core | NETCOREAPP,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.0 | x ≥ 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。