19

如何将编译时间戳信息插入到使用 Visual C++ 2005 构建的可执行文件中?当我执行程序时,我希望能够输出这样的东西:

此版本 XXXX 在 dd-mm-yy, hh:mm 编译。

其中日期和时间反映了项目的构建时间。它们不应该随着程序的每次连续调用而改变,除非它被重新编译。

4

6 回答 6

24

虽然不是您的确切格式,但DATE的格式为 Mmm dd yyyy,而TIME的格式为 hh:mm:ss。您可以创建一个这样的字符串,并在任何对您有意义的打印例程中使用它:

const char *buildString = "This build XXXX was compiled at " __DATE__ ", " __TIME__ ".";

(注意另一个答案:TIMESTAMP只吐出源文件的修改日期/时间,而不是构建日期/时间。)

于 2008-08-25T09:13:52.930 回答
10
__DATE__ 
__TIME__

预定义为 C99 标准的一部分,因此您应该可以使用。它们与预处理器一起运行一次。

于 2008-08-25T08:34:17.707 回答
7

嗯...对于 Visual C++,有一个内置符号叫做__ImageBase. 具体来说:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

您可以在运行时检查以确定 PE 标头中的时间戳:

const IMAGE_NT_HEADERS *nt_header= (const IMAGE_NT_HEADERS *)((char *)&__ImageBase + __ImageBase.e_lfanew);

并用于nt_header->FileHeader.TimeDateStamp获取时间戳,即从 1970 年 1 月 1 日开始的秒数。

于 2008-08-25T15:52:46.763 回答
5

__TIME__并且__DATE__可以工作,但是有一些并发症。

如果您将这些定义放在一个 .h 文件中,并包含来自多个 .c/.cpp 文件的定义,则每个文件将根据其编译时间具有不同版本的日期/时间。因此,如果您希望在两个不同的地方使用日期/时间并且它们应该始终匹配,那么您就有麻烦了。如果您正在进行增量构建,则其中一个文件可能会被重建,而另一个则不会,这再次导致时间戳可能大不相同。

更好的方法是在 .h 文件中制作 GetBuildTimeStamp() 原型,并将__TIME____DATE__宏放入 implementation(.c/.cpp) 文件中。这样,您可以在代码中的多个位置使用时间戳,并且它们将始终匹配。但是,您需要确保每次执行构建时都重新构建 .c/.cpp 文件。如果您正在进行干净的构建,那么此解决方案可能对您有用。

如果您正在进行增量构建,那么您需要确保每次构建都更新构建标记。在 Visual C++ 中,您可以使用 PreBuild 步骤来执行此操作 - 但是在这种情况下,我建议您不要在编译的 .c/.cpp 文件中使用__DATE__和,而是使用__TIME__在程序运行期间在运行时读取的基于文本的文件执行。这使您的构建脚本可以快速更新时间戳(无需编译或链接),并且不需要您的 PreBuild 步骤来了解您的编译器标志或选项。

于 2008-08-25T11:33:12.957 回答
1

我认为,使用DATETIMETIMESTAMP的建议解决方案就足够了。我确实建议获取一个包含在预构建步骤中的触摸程序,以便触摸包含预处理器变量使用的文件。触摸文件可确保其时间戳比上次编译时更新。这样,编译文件中的日期/时间也会随着每次重建而改变。

于 2008-08-25T11:22:17.117 回答
0

Visual C++ 也支持__TIMESTAMP__几乎正是您所需要的。话虽如此,关于构建时间戳的难点在于让它们保持最新,这意味着编译__TIMESTAMP__每次重建时使用的文件。不确定是否有办法在 Visual C++ 中进行设置。

于 2008-08-25T08:59:08.990 回答