.NET Core中如何获取VS2022项目属性内的特定程序集信息?
我尝试获取VS 2022项目属性(同时定义在.csproj文件中)里的以下字段值:
- Authors
- Package
- Version
- Release Notes
- Tags
我用的反射语法是:
var myVar = Assembly.GetEntryAssembly().GetCustomAttribute<Assembly[Attribute]Attribute>().[Attribute];
我能获取大多数属性值(比如Company、Copyright、Description等),但上面列出的字段值拿不到。
我查看了自动生成的文件:
D:\Path\project\obj\Debug\net6.0-windows\project.AssemblyInfo.cs
发现能通过反射拿到的属性都定义在这个文件里,文件内容如下:
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using System; using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("Wm. Eric Brunsen")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright 2018, Wm. Eric Brunsen, All rights reserved")] [assembly: System.Reflection.AssemblyDescriptionAttribute("Shooting Range Management Software")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] [assembly: System.Reflection.AssemblyProductAttribute("Range Manager")] [assembly: System.Reflection.AssemblyTitleAttribute("RangeMgr")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] [assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")] // Generated by the MSBuild WriteCodeFragment class.
我有两个问题:
- 是否有办法获取定义在项目属性UI和.csproj中,但无法通过上述反射语法获取的属性值?
- 由于project.AssemblyInfo.cs文件头部说明它由工具生成,若我向该文件添加属性值,编译时会保留还是丢失?
问题1:获取未映射到程序集特性的.csproj属性值
你提到的Authors、Package、Release Notes、Tags属于NuGet包相关属性,默认不会自动映射到程序集特性里,所以常规反射拿不到。有两种可行方案:
方案1:把.csproj属性映射到自定义程序集特性
先在项目里加一个自定义特性类:
[AttributeUsage(AttributeTargets.Assembly)] public class PackageMetadataAttribute : Attribute { public string Authors { get; set; } public string PackageId { get; set; } public string ReleaseNotes { get; set; } public string Tags { get; set; } }
然后在.csproj里添加配置,让MSBuild自动把属性注入到生成的AssemblyInfo中:
<ItemGroup> <AssemblyAttribute Include="YourNamespace.PackageMetadataAttribute"> <_Parameter1>$(Authors)</_Parameter1> <_Parameter2>$(PackageId)</_Parameter2> <_Parameter3>$(ReleaseNotes)</_Parameter3> <_Parameter4>$(Tags)</_Parameter4> </AssemblyAttribute> </ItemGroup>
编译后,这个自定义特性会出现在自动生成的AssemblyInfo里,就能用反射获取了:
var metadata = Assembly.GetEntryAssembly().GetCustomAttribute<PackageMetadataAttribute>(); string authors = metadata.Authors;
方案2:直接读取.csproj文件
如果可以接受读取文件的方式,直接解析.csproj的XML内容提取属性:
var doc = XDocument.Load("YourProject.csproj"); XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003"; string authors = doc.Descendants(ns + "Authors").FirstOrDefault()?.Value;
注意要处理好文件路径,这种方式只适用于项目文件存在的场景。
另外关于Version:如果是指PackageVersion,可以通过AssemblyInformationalVersionAttribute获取,默认它会和PackageVersion同步;如果是其他版本属性,需要单独配置映射。
问题2:修改自动生成的AssemblyInfo的后果
自动生成的project.AssemblyInfo.cs每次编译(尤其是清理后重新编译)都会被MSBuild覆盖,手动加的内容会完全丢失,绝对不要直接改这个文件。
要自定义程序集特性,正确的做法是:
- 在项目里手动创建一个AssemblyInfo.cs文件(比如放在Properties目录下),MSBuild会自动合并手动文件和自动生成文件的特性,重复特性以手动文件为准。
- 按照问题1的方案1,通过.csproj配置自动注入特性,让工具帮你生成到自动文件里。
内容的提问来源于stack exchange,提问作者Eric B

