我目前有一个应用程序显示构建号在其标题窗口。这很好,除了它对大多数用户没有任何意义,他们想知道他们是否有最新的版本-他们倾向于将其称为“上周四的”而不是1.0.8.4321版本。
计划是把构建日期放在那里,例如“App构建于21/10/2009”。
我正在努力寻找一种程序化的方法,将构建日期作为文本字符串提取出来,以便像这样使用。
对于版本号,我使用:
Assembly.GetExecutingAssembly().GetName().Version.ToString()
在定义了这些是怎么来的之后。
我希望编译日期(和时间,为了加分)也像这样。
非常感谢这里的指示(如果合适的话,借口双关语),或者更整洁的解决方案……
对于。net 5,我已经成功地使用了这种方法。(在这里找到)。
把这个添加到.csproj文件中:
<SourceRevisionId>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</SourceRevisionId>
获取构建日期的方法:
private static DateTime GetBuildDate(Assembly assembly)
{
const string BuildVersionMetadataPrefix = "+build";
var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
if (attribute?.InformationalVersion != null)
{
var value = attribute.InformationalVersion;
var index = value.IndexOf(BuildVersionMetadataPrefix);
if (index > 0)
{
value = value.Substring(index + BuildVersionMetadataPrefix.Length);
if (DateTime.TryParseExact(value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result))
{
return result;
}
}
}
return default;
}
用法:
var buildTime = GetBuildDate(Assembly.GetExecutingAssembly());
buildTime = buildTime.ToLocalTime();
对于. net Core(。NET 5+),可以这样做。它的优点在于不需要添加或嵌入文件,没有T4,也没有预构建脚本。
在你的项目中添加这样一个类:
namespace SuperDuper
{
[AttributeUsage(AttributeTargets.Assembly)]
public class BuildDateTimeAttribute : Attribute
{
public string Date { get; set; }
public BuildDateTimeAttribute(string date)
{
Date = date;
}
}
}
更新项目的.csproj以包含如下内容:
<ItemGroup>
<AssemblyAttribute Include="SuperDuper.BuildDateTime">
<_Parameter1>$([System.DateTime]::Now.ToString("s"))</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
注意,_Parameter1是一个神奇的名字——它意味着BuildDateTime属性类的构造函数的第一个(也是唯一一个)参数。
这就是在程序集中记录构建日期时间所需的全部内容。
然后读取程序集的构建日期时间,执行如下操作:
private static DateTime? getAssemblyBuildDateTime()
{
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var attr = Attribute.GetCustomAttribute(assembly, typeof(BuildDateTimeAttribute)) as BuildDateTimeAttribute;
if (DateTime.TryParse(attr?.Date, out DateTime dt))
return dt;
else
return null;
}
注1(根据评论中的Flydog57):如果你的.csproj有属性GenerateAssemblyInfo在其中列出并设置为false,构建将不会生成程序集信息,你将不会在程序集中获得BuildDateTime信息。因此,要么不要在.csproj中提到GenerateAssemblyInfo(这是新项目的默认行为,如果没有特别设置为false, GenerateAssemblyInfo默认为true),要么显式地将其设置为true。
注2(根据Teddy在评论中的说法):在给出的_Parameter1示例中,我们使用::Now来使用DateTime。现在,这是您的计算机上的本地日期和时间,如果适用日光节约时间和您的本地时区。如果你想使用::UtcNow来使用DateTime,你可以这样做。UtcNow以便将构建日期和时间记录为UTC/GMT。