Re[2]: Программно изменить коментрарии к версии
От: stepaster  
Дата: 08.11.05 14:45
Оценка:
Здравствуйте, McQwerty, Вы писали:

MQ>Разбирался я с такой штукой. Вот движок разбора/замены/сбора VERSION_INFO:


Пример использования:
VOID VWorker::ProcessFileVersion (HINSTANCE hFile, LPCTSTR pszFileName, LPCTSTR pszName, WORD wLangID)
{
    HRSRC hRsrc = FindResourceEx (hFile, RT_VERSION, pszName, wLangID);

    HGLOBAL hVersion = LoadResource (hFile, hRsrc);
    LPVOID pVer = LockResource (hVersion);
    VVersionInfo ver (pVer);
    FreeLibrary (hFile);

    // Здесь можно модифицировать содержимое ver
        VS_FIXEDFILEINFO* pFixed = (VS_FIXEDFILEINFO*) ver. GetPtr (L"", dwLangsSize);

        pFixed -> dwProductVersionMS = m_dwVersionMS;
        pFixed -> dwProductVersionLS = m_dwVersionLS;

        pFixed -> dwFileVersionMS = m_dwVersionMS;
        pFixed -> dwFileVersionLS = m_dwVersionLS;
    // или так (Номера языков брать в "\\VarFileInfo\\Translation")
        ver. ReplaceValue (L"\\StringFileInfo\\????????\\CompanyName", L"bla-bla-bla");

    // pMemoryLocation - просто указатель на кусок памяти
    ZeroMemory (m_pMemoryLocation, 0x10000);
    ver. Compile (m_pMemoryLocation);

    DWORD dwNeededSize = ver. Size ();
    dwNeededSize += (16 - dwNeededSize) & 0xF;

    HANDLE hUpdate = BeginUpdateResource (pszFileName, FALSE);
    BOOL bUpdated = UpdateResource (hUpdate, RT_VERSION, MAKEINTRESOURCE (VS_VERSION_INFO),
        wLangID, m_pMemoryLocation, dwNeededSize);
    EndUpdateResource (hUpdate, FALSE);
} // VWorker::ProcessFileVersion


Возникло несколько вопросов.
1. Что за класс базовый класс VObject у VVersionInfo и VCommonVersionInfo?
2. Не понятнно что тип QBuffer у переменной VCommonVersionInfo::m_Value. Я реализовал этот тип так
    class QBuffer
    {
    public:
        QBuffer(): buffer_(NULL), size_(0) {}
        
        void Assign(BYTE* mem_block, DWORD size)
        {
            buffer_ = mem_block;
            size_ = size;
        }
        BYTE* Get() { return buffer_; }
        
        DWORD Size() { return size_; }
    private:
        BYTE* buffer_;
        DWORD size_;
    };

3. Не знаю что такое VArray поэтому вместо
typedef VArray <VVersionInfo*> VChilds;
использовал vector из STL
typedef std::vector<VVersionInfo*> VChilds;
Надеюсь это тоже не отразилось на функциональности
4. Для того что бы заработало дополнил ваш код из примера.

      LPCTSTR pszFileName = _T("C:\\temp\\sample.exe");
    HINSTANCE hFile = LoadLibrary(pszFileName); 
    LPCTSTR pszName    = MAKEINTRESOURCE(VS_VERSION_INFO);
    WORD wLangID = 10033;

    HRSRC hRsrc = FindResourceEx (hFile, RT_VERSION, pszName, wLangID);

    HGLOBAL hVersion = LoadResource (hFile, hRsrc);
    LPVOID pVer = LockResource (hVersion);
    VVersionInfo ver (pVer);
    FreeLibrary (hFile);

    // Здесь можно модифицировать содержимое ver
    DWORD dwLangsSize;
    VS_FIXEDFILEINFO* pFixed = (VS_FIXEDFILEINFO*)ver.GetPtr(L"", dwLangsSize);

    pFixed->dwProductVersionMS = pFixed->dwProductVersionMS + 0x00010001;//m_dwVersionMS;
    pFixed->dwProductVersionLS = pFixed->dwProductVersionLS + 0x00010001;//m_dwVersionLS;

    pFixed->dwFileVersionMS = pFixed->dwProductVersionMS + 0x00010001;
    pFixed->dwFileVersionLS = pFixed->dwProductVersionMS + 0x00010001;
        //... далее идет обновление

При этом при попытке выполнить
pFixed->dwProductVersionMS = pFixed->dwProductVersionMS + 0x00010001;//m_dwVersionMS;
Появляется окно с Accecc Violation
Я думаю что это связано с тем что слишком рано выполняется FreeLibrary. Но даже если выполнить закрытие библиотеки после всех операций все равно происходит что-то не очень понятное. После обновления ресурса сам файл остается неизменным но в том же каталоге появляется новый с именем RCXxxx.TMP
Последние три xxx в имени файла это шестнадцатиричное число, которое каждый раз изменяется на новое. Если этот файл переименовать в exe то он не запускается.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.