在Visual C ++可执行文件中输出编译时间戳?

时间:2020-03-05 18:42:45  来源:igfitidea点击:

如何将编译时间戳信息插入使用Visual C ++ 2005构建的可执行文件中?我希望能够在执行程序时输出如下内容:

This build XXXX was compiled at dd-mm-yy, hh:mm.

日期和时间反映了项目建立的时间。除非重新编译,否则不应在程序的每次后续调用中更改它们。

解决方案

回答

__DATE__ 
__TIME__

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

回答

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

回答

尽管不是我们确切的格式,但DATE的格式为Mmm dd yyyy,而TIME的格式为hh:mm:ss。我们可以创建一个像这样的字符串,并在任何适合打印例程中使用它:

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

(请注意另一个答案:TIMESTAMP仅显示源文件的修改日期/时间,而不显示生成日期/时间。)

回答

我认为,建议使用DATE,TIME或者TIMESTAMP的解决方案就足够了。我确实建议保留触摸程序,以包括在预构建步骤中,以便触摸保存使用预处理程序变量的文件。触摸文件可确保其时间戳比上次编译时新。这样,每次重新编译时,已编译文件中的日期/时间也会更改。

回答

__TIME__和__DATE__可以工作,但是有一些复杂性。

如果将这些定义放在.h文件中,并包括多个.c / .cpp文件中的定义,则每个文件的日期/时间都将基于其编译时间而有所不同。因此,如果我们希望在两个不同的地方使用日期/时间,并且它们应该始终匹配,那么我们会遇到麻烦。如果我们要进行增量构建,则其中一个文件可能会被重建,而另一个文件则不能被重建,这再次导致时间戳记可能大相径庭。

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

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

回答

嗯...对于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日开始,以秒为单位。