在 Visual C++ 中输出编译时间戳 可执行的?
如何将编译时间戳信息插入到使用 Visual C++ 2005 生成的可执行文件中? 我希望在执行程序时能够输出这样的内容:
此版本 XXXX 是在 dd-mm-yy, hh:mm 编译的。
其中日期和时间反映了项目的构建时间。 它们不应该随着程序的每次连续调用而改变,除非重新编译。
How can I insert compilation timestamp information into an executable I build with Visual C++ 2005? I want to be able to output something like this when I execute the program:
This build XXXX was compiled at dd-mm-yy, hh:mm.
where date and time reflect the time when the project was built. They should not change with each successive call of the program, unless it's recompiled.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
虽然不是您的确切格式,但 DATE 的格式将为 Mmm dd yyyy,而 TIME 的格式将为 hh:mm:ss。 您可以创建一个像这样的字符串,并在任何对您有意义的打印例程中使用它:(
注意另一个答案:TIMESTAMP仅吐出源文件的修改日期/时间,而不是构建日期/时间。)
Though not your exact format, DATE will be of the format Mmm dd yyyy, while TIME will be of the format hh:mm:ss. You can create a string like this and use it in whatever print routine makes sense for you:
(Note on another answer: TIMESTAMP only spits out the modification date/time of the source file, not the build date/time.)
是作为 C99 标准的一部分预定义的,因此您应该可以使用。 它们与预处理器一起运行一次。
are predefined as part of the standards for C99 so should be available to you. They run once with the preprocessor.
嗯...对于 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
获取时间戳,即从 1/1/1970 开始的秒数。Well... for Visual C++, there's a built in symbol called
__ImageBase
. Specifically:EXTERN_C IMAGE_DOS_HEADER __ImageBase;
You can inspect that at runtime to determine the timestamp in the PE header:
const IMAGE_NT_HEADERS *nt_header= (const IMAGE_NT_HEADERS *)((char *)&__ImageBase + __ImageBase.e_lfanew);
And use
nt_header->FileHeader.TimeDateStamp
to get the timestamp, which is seconds from 1/1/1970.__TIME__
和__DATE__
可以工作,但存在一些复杂性。如果将这些定义放在 .h 文件中,并包含多个 .c/.cpp 文件中的定义,则每个文件将根据编译时间而具有不同版本的日期/时间。 因此,如果您希望在两个不同的地方使用日期/时间,并且它们应该始终匹配,那么您就有麻烦了。 如果您正在进行增量构建,其中一个文件可能会被重建,而另一个则不会,这又会导致时间戳可能大不相同。
稍微好一点的方法是在 .h 文件中制作 GetBuildTimeStamp() 原型,并将 __TIME__ 和 __DATE__ 宏放在实现 (.c/.cpp) 文件中。 这样您就可以在代码中的多个位置使用时间戳,并且它们将始终匹配。 但是,您需要确保每次执行构建时都会重建 .c/.cpp 文件。 如果您正在进行干净的构建,那么此解决方案可能适合您。
如果您正在进行增量构建,那么您需要确保每次构建时都会更新构建标记。 在 Visual C++ 中,您可以使用 PreBuild 步骤来完成此操作 - 但是在这种情况下,我建议您不要在已编译的 .c/.cpp 文件中使用
__DATE__
和__TIME__
,而是使用使用在程序执行期间在运行时读取的基于文本的文件。 这使得您的构建脚本可以快速更新时间戳(无需编译或链接),并且不需要您的 PreBuild 步骤来了解编译器标志或选项。__TIME__
and__DATE__
can work, however there are some complications.If you put these definitions in a .h file, and include the definitions from multiple .c/.cpp files, each file will have a different version of the date/time based on when it gets compiled. So if you're looking to use the date/time in two different places and they should always match, you're in trouble. If you're doing an incremental build, one of the files may be rebuilt while the other is not, which again results in time stamps that could be wildly different.
A slightly better approach is to make GetBuildTimeStamp() prototypes in a .h file, and put the
__TIME__
and__DATE__
macros in the implementation(.c/.cpp) file. This way you can use the time stamps in multiple places in your code and they will always match. However you need to ensure that the .c/.cpp file is rebuilt every time a build is performed. If you're doing clean builds then this solution may work for you.If you're doing incremental builds, then you need to ensure the build stamp is updated on every build. In Visual C++ you can do this with PreBuild steps - however in this case I would recommend that instead of using
__DATE__
and__TIME__
in a compiled .c/.cpp file, you use a text-based file that is read at run-time during your program's execution. This makes it fast for your build script to update the timestamp (no compiling or linking required) and doesn't require your PreBuild step to understand your compiler flags or options.我认为,使用 DATE、TIME 或 TIMESTAMP 的建议解决方案就足够了。 我确实建议获取一个触摸程序,将其包含在预构建步骤中,以便触摸保存预处理器变量的使用的文件。 触摸文件可确保其时间戳比上次编译时更新。 这样,编译文件中的日期/时间也会随着每次重建而更改。
I think, the suggested solutions to use DATE, TIME or TIMESTAMP would be good enough. I do recommend to get a hold of a touch program to include in a pre-build step in order to touch the file that holds the use of the preprocessor variable. Touching a file makes sure, that its timestamp is newer than at the time it was last compiled. That way, the date/time in the compiled file is changed as well with each rebuild.
Visual C++ 还支持
__TIMESTAMP__
这几乎正是您所需要的。 话虽这么说,关于构建时间戳的困难部分是保持它们最新,这意味着编译文件,其中每次重建时都使用__TIMESTAMP__
。 但不确定是否有办法在 Visual C++ 中进行设置。Visual C++ also supports
__TIMESTAMP__
which is almost exactly what you need. That being said, the tough part about build timestamps is keeping them up to date, that means compiling the file in which__TIMESTAMP__
is used on every rebuild. Not sure if there's a way to set this up in Visual C++ though.