كيف يمكنني الحصول برمجيا على إصدار ملف DLL أو EXE؟
سؤال
أحتاج إلى الحصول على إصدار المنتج وإصدار الملفات لملف DLL أو EXE باستخدام واجهة برمجة تطبيقات Win32 الأصلية في C أو C ++. انا ليس تبحث عن إصدار Windows، ولكن أرقام الإصدار التي تراها بالنقر بزر الماوس الأيمن على ملف DLL، واختيار "الخصائص"، ثم النظر في علامة التبويب "التفاصيل". هذا عادة ما يكون عدد الإصدار المنقط من أربعة أجزاء XXXX
المحلول
سوف تستخدم getfileversionInfo. API.
يرى باستخدام معلومات الإصدار على موقع MSDN.
عينة:
DWORD verHandle = 0;
UINT size = 0;
LPBYTE lpBuffer = NULL;
DWORD verSize = GetFileVersionInfoSize( szVersionFile, &verHandle);
if (verSize != NULL)
{
LPSTR verData = new char[verSize];
if (GetFileVersionInfo( szVersionFile, verHandle, verSize, verData))
{
if (VerQueryValue(verData,"\\",(VOID FAR* FAR*)&lpBuffer,&size))
{
if (size)
{
VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer;
if (verInfo->dwSignature == 0xfeef04bd)
{
// Doesn't matter if you are on 32 bit or 64 bit,
// DWORD is always 32 bits, so first two revision numbers
// come from dwFileVersionMS, last two come from dwFileVersionLS
TRACE( "File Version: %d.%d.%d.%d\n",
( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
( verInfo->dwFileVersionMS >> 0 ) & 0xffff,
( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
( verInfo->dwFileVersionLS >> 0 ) & 0xffff
);
}
}
}
}
delete[] verData;
}
نصائح أخرى
جميع هذه الحلول لم تنجح بشكل صحيح (مع نظامي). اكتشفت أن كل جزء من الأجزاء الأربعة من رقم الإصدار يتم حفظها كقيمة 16 بت.
يتم حفظ أول رقمين في DWORD DWORD 32 بت، والثاني الثاني في Dwfileversionls. لذلك قمت بتحرير التعليمات البرمجية الخاصة بك في قسم الإخراج مثل هذا:
TRACE( "File Version: %d.%d.%d.%d\n",
( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff,
( pFileInfo->dwFileVersionMS >> 0 ) & 0xffff,
( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff,
( pFileInfo->dwFileVersionLS >> 0 ) & 0xffff
);
ويعمل تماما. يتم تنسيق الإخراج مثل نظامي:
major.minor.build.revision.
يمكنك الحصول على هذه المعلومات باستخدام إصدار معلومات APIS. وبعد هنا عينة:
void PrintFileVersion( TCHAR *pszFilePath )
{
DWORD dwSize = 0;
BYTE *pbVersionInfo = NULL;
VS_FIXEDFILEINFO *pFileInfo = NULL;
UINT puLenFileInfo = 0;
// Get the version information for the file requested
dwSize = GetFileVersionInfoSize( pszFilePath, NULL );
if ( dwSize == 0 )
{
printf( "Error in GetFileVersionInfoSize: %d\n", GetLastError() );
return;
}
pbVersionInfo = new BYTE[ dwSize ];
if ( !GetFileVersionInfo( pszFilePath, 0, dwSize, pbVersionInfo ) )
{
printf( "Error in GetFileVersionInfo: %d\n", GetLastError() );
delete[] pbVersionInfo;
return;
}
if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
{
printf( "Error in VerQueryValue: %d\n", GetLastError() );
delete[] pbVersionInfo;
return;
}
// pFileInfo->dwFileVersionMS is usually zero. However, you should check
// this if your version numbers seem to be wrong
printf( "File Version: %d.%d.%d.%d\n",
( pFileInfo->dwFileVersionLS >> 24 ) & 0xff,
( pFileInfo->dwFileVersionLS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionLS >> 8 ) & 0xff,
( pFileInfo->dwFileVersionLS >> 0 ) & 0xff
);
// pFileInfo->dwProductVersionMS is usually zero. However, you should check
// this if your version numbers seem to be wrong.
printf( "Product Version: %d.%d.%d.%d\n",
( pFileInfo->dwProductVersionLS >> 24 ) & 0xff,
( pFileInfo->dwProductVersionLS >> 16 ) & 0xff,
( pFileInfo->dwProductVersionLS >> 8 ) & 0xff,
( pFileInfo->dwProductVersionLS >> 0 ) & 0xff
);
}
يوضح هذا الرمز أرقام إصدار الملف بشكل صحيح.
( pFileInfo->dwFileVersionMS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionMS >> 0 ) & 0xff,
( pFileInfo->dwFileVersionLS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionLS >> 0 ) & 0xff);
وجدت هذه المقالات ... آسف، لكن ليس لدي خبرة مباشرة مع كيفية القيام بذلك باستخدام واجهات برمجة التطبيقات الأصلية، لذلك تأجلت إلى البحث عن الإنترنت:
- C ++: تحديد رقم إصدار DLL أو قابل للتنفيذ
- VB (ربما الإصدار 6): كيفية استخدام الوظائف في الإصدار.dll
نأمل هذه المساعدة!
أسهل طريقة هي استخدام getfileversioninfoex. أو getfileversionInfo. وظائف API.
يمكنك أيضا القيام بذلك من داخل موارد التطبيق الخاصة بك كما هو موضح هنا.
نظرا لأن أيا من الإجابات ذكر ذلك ... اكتشفت ذلك يجب عليك إجراء حسابات مختلفة اعتمادا إذا كنت تعمل على أنظمة 32 أو 64 بت. وبعد لهذا السبب تجد أن بعض الإجابات في هذا السؤال تعمل من أجلك، والبعض الآخر لا.
إليك تطبيق عينة أستخدمه:
if(IsWow64())
{
// 64 bit build
major = (verInfo->dwProductVersionMS >> 16) & 0xffff;
minor = (verInfo->dwProductVersionMS >> 0) & 0xffff;
revision = (verInfo->dwProductVersionLS >> 16) & 0xffff;
build = (verInfo->dwProductVersionLS >> 0) & 0xffff;
}
else
{
// 32 bit build
major = HIWORD(verInfo->dwProductVersionMS);
minor = LOWORD(verInfo->dwProductVersionMS);
revision = HIWORD(verInfo->dwProductVersionLS);
build = LOWORD(verInfo->dwProductVersionLS);
}
وتنفيذ iswow64 (وليس لي):
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL IsWow64()
{
BOOL bIsWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if(NULL != fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
{
// Handle error...
}
}
return bIsWow64;
}