سؤال

لدي نسخة الموارد في الموارد في C++ المشروع الذي يحتوي على رقم الإصدار ، حقوق الطبع والنشر وبناء التفاصيل.هل هناك طريقة سهلة للوصول إلى هذا في وقت التشغيل إلى ملء بلدي مساعدة/عن الحوار كما أنا حاليا الحفاظ على منفصلة const قيم هذه المعلومات.ومن الناحية المثالية ، ينبغي أن حل العمل على ويندوز/CE المحمول و الإصدارات السابقة من Visual C++ (6.0 وما فوق).

هل كانت مفيدة؟

المحلول

وهذا هو نسخة معدلة من جوابي الأصلي.

bool GetProductAndVersion(CStringA & strProductName, CStringA & strProductVersion)
{
    // get the filename of the executable containing the version resource
    TCHAR szFilename[MAX_PATH + 1] = {0};
    if (GetModuleFileName(NULL, szFilename, MAX_PATH) == 0)
    {
        TRACE("GetModuleFileName failed with error %d\n", GetLastError());
        return false;
    }

    // allocate a block of memory for the version info
    DWORD dummy;
    DWORD dwSize = GetFileVersionInfoSize(szFilename, &dummy);
    if (dwSize == 0)
    {
        TRACE("GetFileVersionInfoSize failed with error %d\n", GetLastError());
        return false;
    }
    std::vector<BYTE> data(dwSize);

    // load the version info
    if (!GetFileVersionInfo(szFilename, NULL, dwSize, &data[0]))
    {
        TRACE("GetFileVersionInfo failed with error %d\n", GetLastError());
        return false;
    }

    // get the name and version strings
    LPVOID pvProductName = NULL;
    unsigned int iProductNameLen = 0;
    LPVOID pvProductVersion = NULL;
    unsigned int iProductVersionLen = 0;

    // replace "040904e4" with the language ID of your resources
    if (!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductName"), &pvProductName, &iProductNameLen) ||
        !VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
    {
        TRACE("Can't obtain ProductName and ProductVersion from resources\n");
        return false;
    }

    strProductName.SetString((LPCSTR)pvProductName, iProductNameLen);
    strProductVersion.SetString((LPCSTR)pvProductVersion, iProductVersionLen);

    return true;
}

نصائح أخرى

لتحصل على نتيجة مستقلة لغة لتغير الجواب مارك:

   // replace "040904e4" with the language ID of your resources
    !VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
{
    TRACE("Can't obtain ProductName and ProductVersion from resources\n");
    return false;
}

ل

UINT                uiVerLen = 0;
VS_FIXEDFILEINFO*   pFixedInfo = 0;     // pointer to fixed file info structure
// get the fixed file info (language-independent) 
if(VerQueryValue(&data[0], TEXT("\\"), (void**)&pFixedInfo, (UINT *)&uiVerLen) == 0)
{
    return false;
}

 strProductVersion.Format("%u.%u.%u.%u", 
    HIWORD (pFixedInfo->dwProductVersionMS),
    LOWORD (pFixedInfo->dwProductVersionMS),
    HIWORD (pFixedInfo->dwProductVersionLS),
    LOWORD (pFixedInfo->dwProductVersionLS));

وشيء من هذا القبيل قد تحصل على انك بدأته، وربما:

TCHAR moduleName[MAX_PATH+1];
(void)GetModuleFileName(AfxGetInstanceHandle(), moduleName, MAX_PATH);
DWORD dummyZero;
DWORD versionSize = GetFileVersionInfoSize(moduleName, &dummyZero);
if(versionSize == 0)
{
    return NULL;
}
void* pVersion = malloc(versionSize);
if(pVersion == NULL)
{
    return NULL;
}
if(!GetFileVersionInfo(moduleName, NULL, versionSize, pVersion))
{
    free(pVersion);
    return NULL;
}

UINT length;
VS_FIXEDFILEINFO* pFixInfo;
VERIFY(VerQueryValue(pVersionInfo, const_cast<LPTSTR>("\\"), (LPVOID*)&pFixInfo, &length));

وشيء من هذا القبيل سوف اعطيكم الوصول الخام لبيانات الموارد والحصول على انك بدأته:

HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(MY_VERSION_ID), RT_VERSION);
DWORD size = ::SizeofResource(NULL, res);
HGLOBAL mem = ::LoadResource(NULL, res);
LPVOID raw_data = ::LockResource(mem);
...
::FreeResource(mem);

وحذار! باستخدام FindResource..LockResource ليس صحيحا. وسوف يعمل أحيانا (كما فعلت في برنامجي تجريبي صغير) وتسبب أحيانا خرق الوصول (على سبيل المثال: رمز الإنتاج I تبذل التجريبي ل).

ووVerQueryValue () الدول الوثائق التي يجب عليك الاتصال GetFileVersionInfoSize وGetFileVersionInfo بدلا من ذلك. ريمون تشن يفسر، انظر http://blogs.msdn.com /oldnewthing/archive/2006/12/26/1365215.aspx

حسنا, قليلا أكثر googleing وجدت التالية على CodeGuru.أساسا يستخدم هذا النهج CFileVersionInfo الكائن للحصول على أي ملف.يجب أن تكون مثيرة للاهتمام أن نرى ما اذا كان يعمل على تشغيلها حاليا .ملف EXE على ويندوز CE.

وأحيانا أتلقى انتهاك وصول عند استخدام VerQueryValueA. لكنني لم يحصل هذا الخطأ عند استخدام VerQueryValueW. أعتقد أن هناك شيئا خاطئا مع VerQueryValueA في version.dll. لذلك يمكنني استخدام VerQueryValueW بدلا من VerQueryValueA حتى في مشاريع متعددة البايت ترميز الأحرف. هنا هو قانون بلدي وظيفة ReadVersion

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top