Тут ясно видно какие версии компонентов программы упали. Как же можно извлеч эту информацию?
Сначала я подумал, что надо использовать VERSIONINFO, но как выяснилось эти данные надо отдельно описывать в ресурсном файле (.rc) и отдельно вкомпилять в экзешник.
Затем мне объяснили что время сборки добавляется линкером в специальном заголовке. Все эти exe/dll являются файлами формата Portable Executable и в состав вижуал студии даже входит специальная утилита dumpbin, с помощью которой эти загаловки можно просмотреть:
> dumpbin /all lib.dll
------------------8-<-------------------------------------------
FILE HEADER VALUES
14C machine (x86)
5 number of sections
4DD3E95F time date stamp Wed May 18 19:44:31 2011 ← Вот оно!
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
---------------8-<----------------------------------
Если это смог извлечь dumpbin, то сможем и мы. В файле windows.h описана структура
IMAGE_DOS_HEADERS и IMAGE_NT_HEADERS. В файле они расположены подряд, один за другим. Адрес следующего заголовка лежит в IMAGE_DOS_HEADERS::e_lfanew. Само же время сборки лежит тут: IMAGE_NT_HEADERS::IMAGE_FILE_HEADER::FileHeader.TimeDateStamp (в секундах с начала эпохи UNIX).
Получается такой код:
void print_timestamp(QString fpath)
{
IMAGE_NT_HEADERS header = {0};
IMAGE_DOS_HEADER dosHeader = {0};
QFile f(fpath);
if (!f.open(QIODevice::ReadOnly))
{
return;
}
f.read(reinterpret_cast<char*>(&dosHeader), sizeof(dosHeader));
if (dosHeader.e_magic == IMAGE_DOS_SIGNATURE
&& f.seek(dosHeader.e_lfanew)
&& f.read(reinterpret_cast<char*>(&header), sizeof(header)))
{
QDateTime dt;
dt.setTime_t(header.FileHeader.TimeDateStamp);
qDebug("Timestamp: 0x%0X (%s UTC)",
header.FileHeader.TimeDateStamp,
qPrintable(dt.toUTC().toString("dd.MM.yyyy hh:mm:ss")));
}
f.close();
}
Рекомендую изучить: хорошая статья о PE формате
Комментариев нет:
Отправить комментарий