错误信息:
// checkversion.cpp
// compile with: /link version.lib
#include <windows.h>
#include <stdio.h>
void EmitErrorMsg (HRESULT hr);
HRESULT GetFileVersion (char *filename, VS_FIXEDFILEINFO *vsf);
HRESULT GetFileDate (char *filename, FILETIME *pft);
HRESULT LastError();
int WhichIsNewer (char *fname1, char *fname2);
void printtime (FILETIME *t) {
FILETIME lft;
FILETIME *ft = &lft;
FileTimeToLocalFileTime(t,ft);
printf("%08x %08x",ft->dwHighDateTime,ft->dwLowDateTime); {
SYSTEMTIME stCreate;
BOOL bret = FileTimeToSystemTime(ft,&stCreate);
printf(" %02d/%02d/%d %02d:%02d:%02d\n",
stCreate.wMonth, stCreate.wDay, stCreate.wYear,
stCreate.wHour, stCreate.wMinute, stCreate.wSecond);
}
}
int main(int argc, char* argv[]) {
printf("usage: checkversion file1 file2\n"
"\tReports which file is newer, first by checking the file version in "
"\tthe version resource, then by checking the date\n\n" );
if (argc != 3)
return 1;
int newer = WhichIsNewer(argv[1],argv[2]);
switch(newer) {
case 1:
case 2: printf("%s is newer\n",argv[newer]); break;
case 3: printf("they are the same version\n"); break;
case 0:
default: printf("there was an error\n"); break;
}
return !newer;
}
int WhichIsNewer (char *fname1, char *fname2) {
// 1 if argv[1] is newer
// 2 if argv[2] is newer
// 3 if they are the same version
// 0 if there is an error
int ndxNewerFile;
HRESULT ret;
VS_FIXEDFILEINFO vsf1,vsf2;
if ( SUCCEEDED((ret=GetFileVersion(fname1,&vsf1))) && SUCCEEDED((ret=GetFileVersion(fname2,&vsf2)))) {
// both files have a file version resource
// compare by file version resource
if (vsf1.dwFileVersionMS > vsf2.dwFileVersionMS) {
ndxNewerFile = 1;
}
else
if (vsf1.dwFileVersionMS < vsf2.dwFileVersionMS) {
ndxNewerFile = 2;
}
else { // if (vsf1.dwFileVersionMS == vsf2.dwFileVersionMS)
if (vsf1.dwFileVersionLS > vsf2.dwFileVersionLS) {
ndxNewerFile = 1;
}
else if (vsf1.dwFileVersionLS < vsf2.dwFileVersionLS) {
ndxNewerFile = 2;
}
else { // if (vsf1.dwFileVersionLS == vsf2.dwFileVersionLS)
ndxNewerFile = 3;
}
}
}
else {
// compare by date
FILETIME ft1,ft2;
if (SUCCEEDED((ret=GetFileDate(fname1,&ft1))) && SUCCEEDED((ret=GetFileDate(fname2,&ft2))))
{
LONG x = CompareFileTime(&ft1,&ft2);
if (x == -1)
ndxNewerFile = 2;
else
if (x == 0)
ndxNewerFile = 3;
else
if (x == 1) ndxNewerFile = 1;
else {
EmitErrorMsg(E_FAIL);
return 0;
}
}
else {
EmitErrorMsg(ret);
return 0;
}
}
return ndxNewerFile;
}
HRESULT GetFileDate (char *filename, FILETIME *pft) {
// we are interested only in the create time
// this is the equiv of "modified time" in the
// Windows Explorer properties dialog
FILETIME ct,lat;
HANDLE hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if (hFile == INVALID_HANDLE_VALUE)
return LastError();
BOOL bret = GetFileTime(hFile,&ct,&lat,pft);
if (bret == 0)
return LastError();
return S_OK;
}
// This function gets the file version info structure
HRESULT GetFileVersion (char *filename, VS_FIXEDFILEINFO *pvsf) {
DWORD dwHandle;
DWORD cchver = GetFileVersionInfoSize(filename,&dwHandle);
if (cchver == 0)
return LastError();
char* pver = new char[cchver];
BOOL bret = GetFileVersionInfo(filename,dwHandle,cchver,pver);
if (!bret)
return LastError();
UINT uLen;
void *pbuf;
bret = VerQueryValue(pver,"\\",&pbuf,&uLen);
if (!bret)
return LastError();
memcpy(pvsf,pbuf,sizeof(VS_FIXEDFILEINFO));
delete[] pver;
return S_OK;
}
HRESULT LastError () {
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr))
return E_FAIL;
return hr;
}
// This little function emits an error message based on WIN32 error messages
void EmitErrorMsg (HRESULT hr) {
char szMsg[1024];
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
szMsg,
1024,
NULL
);
printf("%s\n",szMsg);
}