在.NET MAUI的csproj中获取构建日期遇编译错误,求解决及替代方法
.NET MAUI运行时获取构建日期的替代方案
在.NET MAUI项目里直接用WPF那套在csproj版本字段嵌入$([System.DateTime]::Now.ToString())的写法会触发NETSDK1005错误,因为MAUI的项目系统对版本格式校验更严格,没法直接嵌入动态日期字符串。如果ApplicationDisplayVersion满足不了需求,试试下面几种运行时获取构建日期的方法:
方法一:通过MSBuild常量注入构建日期
- 在项目的csproj文件里添加以下配置:
<PropertyGroup> <!-- 用UTC时间避免时区问题,格式可自行调整 --> <BuildDate>$([System.DateTime]::UtcNow.ToString("yyyy-MM-dd HH:mm:ss"))</BuildDate> </PropertyGroup> <ItemGroup> <CompileConstant Include="BUILD_DATE="$(BuildDate)"" /> </ItemGroup>
- 在C#代码里直接使用生成的常量:
string buildDate = BUILD_DATE;
这里要注意用转义引号"确保常量能正确生成字符串值。
方法二:读取程序集PE头的链接器时间戳
.NET程序集的PE文件头里存储了编译时的时间戳,通过反射和文件读取就能拿到:
using System.Reflection; using System.Runtime.InteropServices; using System.IO; public static DateTime GetAssemblyBuildDate() { var assembly = Assembly.GetExecutingAssembly(); var assemblyPath = assembly.Location; const int peHeaderOffset = 60; const int linkerTimestampOffset = 8; var buffer = new byte[2048]; using (var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read)) { stream.Read(buffer, 0, 2048); } var peHeaderPosition = BitConverter.ToInt32(buffer, peHeaderOffset); var linkerTimestamp = BitConverter.ToInt32(buffer, peHeaderPosition + linkerTimestampOffset); var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var buildUtcDate = epoch.AddSeconds(linkerTimestamp); // 转换为本地时间,跨平台时自动适配 return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? buildUtcDate.ToLocalTime() : buildUtcDate; }
这种方法不需要修改csproj,直接通过代码读取,缺点是时间戳是链接器生成的,和实际构建时间可能有几秒误差。
方法三:嵌入构建日期到资源文件
- 在csproj里添加配置,生成包含构建日期的嵌入资源:
<PropertyGroup> <BuildDate>$([System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss"))</BuildDate> </PropertyGroup> <ItemGroup> <EmbeddedResource Include="BuildDate.txt"> <Generator>MSBuild:GenerateResource</Generator> <LastGenOutput>BuildDate.txt</LastGenOutput> <Content>$(BuildDate)</Content> </EmbeddedResource> </ItemGroup>
- 在代码里读取嵌入的资源文件:
using System.Reflection; using System.IO; public static string GetBuildDateFromResource() { var assembly = Assembly.GetExecutingAssembly(); // 替换成你的项目命名空间+文件名,比如"MyMauiApp.BuildDate.txt" var resourceFullName = $"{assembly.GetName().Name}.BuildDate.txt"; using (var stream = assembly.GetManifestResourceStream(resourceFullName)) using (var reader = new StreamReader(stream)) { return reader.ReadToEnd().Trim(); } }
这种方式适合需要将构建日期作为独立资源管理的场景,记得替换正确的资源全名。
内容的提问来源于stack exchange,提问作者Freudi
相关产品推荐
相关产品推荐

