我目前有一个应用程序显示构建号在其标题窗口。这很好,除了它对大多数用户没有任何意义,他们想知道他们是否有最新的版本-他们倾向于将其称为“上周四的”而不是1.0.8.4321版本。
计划是把构建日期放在那里,例如“App构建于21/10/2009”。
我正在努力寻找一种程序化的方法,将构建日期作为文本字符串提取出来,以便像这样使用。
对于版本号,我使用:
Assembly.GetExecutingAssembly().GetName().Version.ToString()
在定义了这些是怎么来的之后。
我希望编译日期(和时间,为了加分)也像这样。
非常感谢这里的指示(如果合适的话,借口双关语),或者更整洁的解决方案……
我需要一个通用的解决方案,可以在任何平台(iOS、Android和Windows)上与NETStandard项目一起工作。为了实现这一点,我决定通过PowerShell脚本自动生成CS文件。下面是PowerShell脚本:
param($outputFile="BuildDate.cs")
$buildDate = Get-Date -date (Get-Date).ToUniversalTime() -Format o
$class =
"using System;
using System.Globalization;
namespace MyNamespace
{
public static class BuildDate
{
public const string BuildDateString = `"$buildDate`";
public static readonly DateTime BuildDateUtc = DateTime.Parse(BuildDateString, null, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
}
}"
Set-Content -Path $outputFile -Value $class
将PowerScript文件保存为GenBuildDate。Ps1,并添加到你的项目。最后,添加以下行到您的预构建事件:
powershell -File $(ProjectDir)GenBuildDate.ps1 -outputFile $(ProjectDir)BuildDate.cs
确保项目中包含BuildDate.cs。在任何操作系统上都像冠军一样!
对于. net Core项目,我修改了Postlagerkarte的答案,用构建日期更新程序集版权字段。
直接编辑csproj
以下内容可以直接添加到csproj中的第一个PropertyGroup:
<Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>
替代方案:Visual Studio项目属性
或者直接将内部表达式粘贴到Visual Studio中项目属性Package部分的Copyright字段中:
Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))
这可能有点令人困惑,因为Visual Studio将计算表达式并在窗口中显示当前值,但它也将在幕后适当地更新项目文件。
通过Directory.Build.props实现解决方案范围
您可以将上面的<Copyright>元素放入解决方案根目录下的directory . build .props文件中,并将其自动应用于该目录中的所有项目,假设每个项目不提供自己的Copyright值。
<Project>
<PropertyGroup>
<Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>
</PropertyGroup>
</Project>
props:自定义构建
输出
示例表达式将为您提供如下版权:
Copyright © 2018 Travis Troyer (2018-05-30T14:46:23)
检索
你可以在Windows中从文件属性中查看版权信息,或者在运行时获取它:
var version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);
Console.WriteLine(version.LegalCopyright);
Jeff Atwood在《艰难地确定构建日期》中谈到了这个问题。
最可靠的方法是从可执行文件中嵌入的PE头中检索链接器时间戳——一些c#代码(由Joe Spivey编写)来自Jeff文章的注释:
public static DateTime GetLinkerTime(this Assembly assembly, TimeZoneInfo target = null)
{
var filePath = assembly.Location;
const int c_PeHeaderOffset = 60;
const int c_LinkerTimestampOffset = 8;
var buffer = new byte[2048];
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
stream.Read(buffer, 0, 2048);
var offset = BitConverter.ToInt32(buffer, c_PeHeaderOffset);
var secondsSince1970 = BitConverter.ToInt32(buffer, offset + c_LinkerTimestampOffset);
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var linkTimeUtc = epoch.AddSeconds(secondsSince1970);
var tz = target ?? TimeZoneInfo.Local;
var localTime = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tz);
return localTime;
}
使用的例子:
var linkTimeLocal = Assembly.GetExecutingAssembly().GetLinkerTime();
注意:这个方法适用于。net Core 1.0,但在。net Core 1.1之后就不再适用了——它给出的年份是1900-2020年之间的随机值。