如何从C#中的预编译器获取当前日期时间?
在C#3.0中,我有一个属性,假设它包含类的版本。版本号只是编译的日期和时间。现在,我有以下代码:如何从C#中的预编译器获取当前日期时间?,c#,.net,c-preprocessor,C#,.net,C Preprocessor,在C#3.0中,我有一个属性,假设它包含类的版本。版本号只是编译的日期和时间。现在,我有以下代码: public DateTime Version { get { return DateTime.UtcNow; } } 显然,这是错误的,因为这个属性返回我当前的日期和时间那么,预编译器是否可以在编译时打印日期时间?在这种情况下,我可以执行类似于下面的操作 public DateTime Version { get { return new DateTime("PRECOMPIL
public DateTime Version
{
get { return DateTime.UtcNow; }
}
显然,这是错误的,因为这个属性返回我当前的日期和时间那么,预编译器是否可以在编译时打印日期时间?在这种情况下,我可以执行类似于下面的操作
public DateTime Version
{
get { return new DateTime("PRECOMPILER DATE"); }
}
C#没有宏的概念;但是,您可以在编译源代码之前使用构建脚本中的其他工具(csproj/NANT/etc)来操作源代码。例如,我使用它将修订号设置为当前SVN修订
一个便宜的选项是预构建事件(您可以通过VS中的“项目属性”对话框执行此操作):本质上是在构建之前运行的bat文件;然后,您可以编写所需的任何更改。一个更复杂的选项是构建任务
例如,实用程序库包括时间
任务和文件更新
任务;从理论上讲,应该可以将两者链接在一起,以模仿您的需要
就个人而言,我会使用[AssemblyVersion]
详细信息,而不是时间-如果您将其链接到您的源代码管理系统,这将很容易找到有问题的版本;因此,对于我的SVN版本,我使用(在我的构建项目中):
...
...
现在,我的程序集版本是正确的,包括操作系统报告的文件版本。C中的
\uuuuu TIME\uuuu
预处理器指令没有等价物,最好是获取当前程序集并获取创建日期,它将包含编译时间。请参阅 < P> >我认为C语言C++中没有一种方法可以这样定义宏定义被明确禁止。
您可以使用程序集的最后修改日期来解决此问题,或者可能包含一个文本文件作为嵌入资源,并添加一个将当前日期/时间写入其中的自定义生成操作。没有预处理器
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu指令,但是您可以使用其他东西,例如程序集的创建时间。您也可以考虑从源代码管理系统中使用关键字替换(在Sub版本中$DATA $)。
该编号可以从程序集的元数据中检索,并且可以设置为与生成日期匹配
通常,您会在AssemblyInfo.cs文件中找到或创建一个条目。使用Visual Studio创建项目时。例如:
[assembly: AssemblyVersion("1.0.*")]
上的文档的报价。(我将一些重要部分用黑体标出)
您可以指定所有值,也可以
可以接受默认的内部版本号,
修订号,或使用
星号()。例如
[组件:组件版本(“2.3.25.1”)]
指示2为主要版本,3为
次要版本,25作为版本
编号,1作为修订号。
版本号,例如
[汇编:汇编版本(“1.2”)]
指定1为主要版本,2为
次要版本,并接受
默认版本号和修订号。A
版本号,例如
[组件:组件版本(“1.2.15.*)]
指定1为主要版本,2为
次要版本,15作为版本
编号,并接受默认值
修订号默认生成
数字每天递增。默认值
修订号是随机的。
如您所见,如果您可以使用此设置默认的内部版本号。默认生成编号是每天递增的值
然后,可以使用属性检索生成编号。MSDN提供的示例应该会让您开始学习
默认生成编号是自2000年1月1日起的天数
也有一个关于如何使用这个的清晰解释。你想要这样的东西吗:
(获取通过版本信息生成程序集的日期;生成编号为自2000年1月1日起的天数)
这不是真的,构建编号可以是您想要的任何内容,并且在实际执行发布时可能会更改。你不能依靠你的版本号来知道编译是什么时候发生的。是的,版本号可以是你想要的任何东西,但是默认的版本号,在版本中使用“*”生成的版本号是从2000年1月1日起的天数。我已经把我的答案说得更清楚了。我希望现在不会混淆用户设置的版本号和生成的默认版本号。即使人们使用默认版本号,每天的增量也只提供版本日期。OP要求提供日期和时间,我在MSBuild中使用Microsoft SDC任务执行类似的操作:指向源的过时链接(重定向到主页)?该页面已删除。
private DateTime RetrieveLinkerTimestamp() {
string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
const int c_PeHeaderOffset = 60;
const int c_LinkerTimestampOffset = 8;
byte[] b = new byte[2048];
System.IO.Stream s = null;
try {
s = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
s.Read(b, 0, 2048);
} finally {
if (s != null) {
s.Close();
}
}
int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);
dt = dt.AddSeconds(secondsSince1970);
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
return dt;
}
[assembly: AssemblyVersion("1.0.*")]
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime versionsDatum = new DateTime(2000, 1, 1);
versionsDatum = versionsDatum.AddDays(version.Build);