Программно изменить коментрарии к версии
От: stepaster  
Дата: 07.11.05 15:16
Оценка:
Существует готовый exe файл. Нужно в ресурсе version этого файла программно изменить коментарии (пункт Comments). Пробовал способо описанным здесь http://www.codeproject.com/samples/UpdateVersion.asp не получилось, exe-шник перестает запускаться после внесения изменений.
Re: Программно изменить коментрарии к версии
От: McQwerty Россия  
Дата: 07.11.05 15:56
Оценка: 7 (1)
Здравствуйте, stepaster, Вы писали:

S>Существует готовый exe файл. Нужно в ресурсе version этого файла программно изменить коментарии (пункт Comments). Пробовал способо описанным здесь http://www.codeproject.com/samples/UpdateVersion.asp не получилось, exe-шник перестает запускаться после внесения изменений.


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

Заголовок:
class VVersionInfo: public VObject
{
public:
    class VCommonVersionInfo: public VObject
    {
    public:
        VCommonVersionInfo (LPCVOID pMemoryLocation, DWORD nLevel);
        virtual ~VCommonVersionInfo ();

    public:
        DWORD Size () const;
        DWORD HeaderSize () const;
        DWORD ChildSize () const;
        BOOL Compile (LPVOID pMemoryLocation);
        VOID ReplaceValue (LPCVOID pValue, DWORD dwSize);
        DWORD RealSize () const;

    public:
        WORD m_wLength;
        WORD m_wValueLength;
        WORD m_wType;
        LPWSTR m_pszKey;
        QBuffer m_Value;
        DWORD m_nSize;
        DWORD m_nLevel;
    }; // VCommonVersionInfo

public:
    VVersionInfo (const LPVOID pMemoryLocation, DWORD nLevel = 0);
    virtual ~VVersionInfo ();

public:
    DWORD Size () const;
    BOOL Compile (LPVOID pMemoryLocation) const;
    BOOL ReplaceValue (LPCWSTR pszPath, LPCVOID pValue, DWORD dwSize);
    BOOL ReplaceValue (LPCWSTR pszPath, LPCWSTR pszValue);
    LPBYTE GetPtr (LPCWSTR pszPath, DWORD& dwSize);
    VVersionInfo* Find (LPWSTR pszKey) const;

public:
    typedef VArray <VVersionInfo*> VChilds;

    VCommonVersionInfo* m_pInfo;
    VChilds m_Childs;
}; // VVersionInfo


Исходник:
#include "stdafx.h"

#ifndef __verInfo_h
    #include "verInfo.h"
#endif

/*****************************************************************************/

VVersionInfo::VCommonVersionInfo::VCommonVersionInfo (LPCVOID pMemoryLocation, DWORD nLevel)
{
    const LPBYTE pTemp = (LPBYTE) pMemoryLocation;

    m_nSize = 0;
    m_nLevel = nLevel;

    m_wLength = * ((LPWORD) (pTemp + m_nSize));            m_nSize += sizeof (WORD);
    m_wValueLength = * ((LPWORD) (pTemp + m_nSize));    m_nSize += sizeof (WORD);
    m_wType =  * ((LPWORD) (pTemp + m_nSize));            m_nSize += sizeof (WORD);

    m_pszKey = _wcsdup ((LPCWSTR) (pTemp + m_nSize));
    m_nSize += (wcslen (m_pszKey) + 1) * sizeof (WCHAR);

    m_nSize += (4 - m_nSize) & 3;    // выравнивание на 32 бита

    DWORD dwFactor = (m_nLevel == 3) ? sizeof (WORD) : 1;
    m_Value. Assign (pTemp + m_nSize, m_wValueLength * dwFactor);
    m_nSize += m_wValueLength * dwFactor;
    
    m_nSize += (4 - m_nSize) & 3;    // выравнивание на 32 бита
} // VVersionInfo::VCommonVersionInfo::VCommonVersionInfo

DWORD VVersionInfo::VCommonVersionInfo::HeaderSize () const
{
    DWORD nSize = (sizeof (WORD) * 3) + ((wcslen (m_pszKey) + 1) * sizeof (WCHAR));

    return nSize + ((4 - nSize) & 3);
} // VVersionInfo::VCommonVersionInfo::HeaderSize

VVersionInfo::VCommonVersionInfo::~VCommonVersionInfo ()
{
    free (m_pszKey);
} // VVersionInfo::VCommonVersionInfo::~VCommonVersionInfo

DWORD VVersionInfo::VCommonVersionInfo::Size () const
{
    return m_nSize;
} // VVersionInfo::VCommonVersionInfo::Size

VOID VVersionInfo::VCommonVersionInfo::ReplaceValue (LPCVOID pValue, DWORD dwSize)
{
    DWORD dwFactor = (m_nLevel == 3) ? sizeof (WORD) : 1;
    m_wValueLength = (WORD) (dwSize / dwFactor);
    m_Value. Assign ((LPBYTE) pValue, dwSize);

    m_nSize = m_wLength = (WORD) (RealSize ());
} // VVersionInfo::VCommonVersionInfo::ReplaceValue

BOOL VVersionInfo::VCommonVersionInfo::Compile (LPVOID pMemoryLocation)
{
    LPBYTE pTemp = (LPBYTE) pMemoryLocation;

    DWORD nOffset = 0;

    DWORD dwFactor = (m_nLevel == 3) ? sizeof (WORD) : 1;
    * ((LPWORD) (pTemp + nOffset)) = m_wLength;            nOffset += sizeof (WORD);
    * ((LPWORD) (pTemp + nOffset)) = m_wValueLength;    nOffset += sizeof (WORD);
    * ((LPWORD) (pTemp + nOffset)) = m_wType;            nOffset += sizeof (WORD);

    wcscpy ((LPWSTR) (pTemp + nOffset), m_pszKey);
    nOffset += (wcslen (m_pszKey) + 1) * sizeof (WCHAR);

    if (m_Value. Size ())
    {
        nOffset += (4 - nOffset) & 3;    // выравнивание на 32 бита
        CopyMemory (pTemp + nOffset, m_Value. Get (), m_Value. Size ());
        nOffset += m_Value. Size ();
    }

    nOffset += (4 - nOffset) & 3;    // выравнивание на 32 бита

    m_nSize = nOffset;

    return TRUE;
} // VVersionInfo::VCommonVersionInfo::Compile

DWORD VVersionInfo::VCommonVersionInfo::ChildSize () const
{
    if (m_nSize < m_wLength)
    {
        DWORD nResult = m_wLength - m_nSize;
        return nResult + ((4 - nResult) & 3);
    }
    else
        return 0;
} // VVersionInfo::VCommonVersionInfo::ChildSize

DWORD VVersionInfo::VCommonVersionInfo::RealSize () const
{
    DWORD nSize = HeaderSize ();
    if (m_wValueLength)
    {
        DWORD dwFactor = (m_nLevel == 3) ? sizeof (WORD) : 1;
        nSize += m_wValueLength * dwFactor;
        nSize += ((4 - nSize) & 3);
    }

    return nSize;
} // VVersionInfo::VCommonVersionInfo::RealSize

/*****************************************************************************/

VVersionInfo::VVersionInfo (const LPVOID pMemoryLocation, DWORD nLevel)
{
    LPBYTE pTemp = (LPBYTE) pMemoryLocation;
    m_pInfo = new VCommonVersionInfo (pMemoryLocation, nLevel);
    INT dwSizeRest = m_pInfo -> ChildSize ();
    pTemp += m_pInfo -> Size ();

    while (dwSizeRest > 0)
    {
        VVersionInfo* pChild = new VVersionInfo (pTemp, nLevel + 1);
        m_Childs. Add (pChild);
        DWORD dwItemSize = pChild -> Size ();
        pTemp += dwItemSize;
        dwSizeRest -= dwItemSize;

        if (dwSizeRest < 0)
        {
            dwSizeRest = 0;
        }
    }
} // VVersionInfo::VVersionInfo

BOOL VVersionInfo::Compile (LPVOID pMemoryLocation) const
{
    LPBYTE pTemp = (LPBYTE) pMemoryLocation;

    m_pInfo -> m_wLength = (WORD) Size ();
    m_pInfo -> Compile (pTemp);
    pTemp += m_pInfo -> Size ();

    for (INT i = 0; i < m_Childs. Count (); i ++)
    {
        m_Childs [i] -> Compile (pTemp);
        pTemp += m_Childs [i] -> Size ();
    }

    return TRUE;
} // VVersionInfo::Compile

VVersionInfo::~VVersionInfo ()
{
    delete m_pInfo;
} // VVersionInfo::~VVersionInfo

DWORD VVersionInfo::Size () const
{
    DWORD nSize = m_pInfo -> RealSize ();

    for (INT i = 0; i < m_Childs. Count (); i ++)
        nSize += m_Childs [i] -> Size ();

    return nSize;
} // VVersionInfo::Size

VVersionInfo* VVersionInfo::Find (LPWSTR pszKey) const
{
    for (INT i = 0; i < m_Childs. Count (); i ++)
        if (wcsicmp (pszKey, m_Childs [i] -> m_pInfo -> m_pszKey) == 0)
            return m_Childs [i];

    return NULL;
} // VVersionInfo::Find

BOOL VVersionInfo::ReplaceValue (LPCWSTR pszPath, LPCVOID pValue, DWORD dwSize)
{
    LPWSTR pszKeyPath = wcsdup (pszPath);
    LPWSTR pszKey = wcstok (pszKeyPath, L"\\");

    VVersionInfo *pLevel = this;

    while (pszKey)
    {
        pLevel = pLevel -> Find (pszKey);
        if (!pLevel) break;
        pszKey = wcstok (NULL, L"\\");
    }

    if (pLevel)
        pLevel -> m_pInfo -> ReplaceValue (pValue, dwSize);

    free (pszKeyPath);

    return pLevel != NULL;
} // VVersionInfo::ReplaceValue

BOOL VVersionInfo::ReplaceValue (LPCWSTR pszPath, LPCWSTR pszValue)
{
    return ReplaceValue (pszPath, pszValue, (wcslen (pszValue) + 1) * sizeof (WCHAR));
} // VVersionInfo::ReplaceValue

LPBYTE VVersionInfo::GetPtr (LPCWSTR pszPath, DWORD& dwSize)
{
    LPWSTR pszKeyPath = wcsdup (pszPath);
    LPWSTR pszKey = wcstok (pszKeyPath, L"\\");
    dwSize = 0;

    VVersionInfo *pLevel = this;

    while (pszKey)
    {
        pLevel = pLevel -> Find (pszKey);
        if (!pLevel) break;
        pszKey = wcstok (NULL, L"\\");
    }

    if (pLevel)
    {
        dwSize = pLevel -> m_pInfo -> m_Value. Size ();
        return pLevel -> m_pInfo -> m_Value. Get ();
    }

    return NULL;
} // VVersionInfo::GetPtr


Пример использования:
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
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 то он не запускается.
Re[3]: Программно изменить коментрарии к версии
От: McQwerty Россия  
Дата: 20.11.05 12:18
Оценка:
S>Возникло несколько вопросов.
S>1. Что за класс базовый класс VObject у VVersionInfo и VCommonVersionInfo?
Обычный базовый класс "всего". Можно игнорировать...
S>2. Не понятнно что тип QBuffer у переменной VCommonVersionInfo::m_Value. Я реализовал этот тип так
Это просто буфер на н-цать байт. В отличии от восстановленного варианта содержит копию данных
S>
    class QBuffer
    {
    public:
        QBuffer ();
        QBuffer (DWORD dwSize);
        QBuffer (QBuffer& aBuffer);
        QBuffer (LPBYTE lpData, DWORD dwSize);
        virtual ~QBuffer ();

    public:
        VOID Allocate (DWORD dwSize);
        VOID Assign (LPBYTE lpData, DWORD dwSize);
        VOID Set (LPBYTE lpData, DWORD dwSize);

    public:
        LPBYTE Get () const;
        DWORD Size () const;

    protected:
        VOID allocate (LPBYTE lpData, DWORD dwSize);
        VOID deallocate ();
        VOID initialize ();

    private:
        LPBYTE lpBuffer;
        DWORD dwBufferSize;
    }; // QBuffer


VOID QBuffer::initialize ()
{
    lpBuffer = NULL;
    dwBufferSize = 0;
} // QBuffer::initialize

QBuffer::QBuffer ()
{
    initialize ();
    allocate (NULL, 0);
} // QBuffer::QBuffer

QBuffer::QBuffer (DWORD dwSize)
{
    initialize ();
    allocate (NULL, dwSize);
} // QBuffer::QBuffer

QBuffer::QBuffer (QBuffer& aBuffer)
{
    initialize ();
    allocate (aBuffer. Get (), aBuffer. Size ());
} // QBuffer::QBuffer

QBuffer::QBuffer (LPBYTE lpData, DWORD dwSize)
{
    initialize ();
    allocate (lpData, dwSize);
} // QBuffer::QBuffer

QBuffer::~QBuffer ()
{
    deallocate ();
} // QBuffer::~QBuffer

VOID QBuffer::allocate (LPBYTE lpData, DWORD dwSize)
{
    deallocate ();

    if (dwSize)
    {
        lpBuffer = (LPBYTE) GlobalAlloc (GPTR, dwSize);

        if (lpBuffer)
        {
            if (lpData)
                CopyMemory (lpBuffer, lpData, dwSize);

            dwBufferSize = dwSize;
        }
        else
            dwBufferSize = 0;
    }
} // QBuffer::allocate

VOID QBuffer::deallocate ()
{
    if (lpBuffer)
    {
        GlobalFree ((HGLOBAL) lpBuffer);
        lpBuffer = NULL;
    }

    dwBufferSize = 0;

    initialize ();
} // QBuffer::deallocate

LPBYTE QBuffer::Get () const { return lpBuffer; }
DWORD QBuffer::Size () const { return dwBufferSize; }

VOID QBuffer::Allocate (DWORD dwSize)
{
    allocate (NULL, dwSize);
} // QBuffer::Allocate

VOID QBuffer::Assign (LPBYTE lpData, DWORD dwSize)
{
    allocate (lpData, dwSize);
} // QBuffer::Assign

VOID QBuffer::Set (LPBYTE lpData, DWORD dwSize)
{
    deallocate ();
    lpBuffer = lpData;
    dwBufferSize = dwSize;
} // QBuffer::Set
S>

S>3. Не знаю что такое VArray поэтому вместо
S> typedef VArray <VVersionInfo*> VChilds;
S> использовал vector из STL
S> typedef std::vector<VVersionInfo*> VChilds;
S> Надеюсь это тоже не отразилось на функциональности
Вполне подойдёт...

S>4. Для того что бы заработало дополнил ваш код из примера.


S> При этом при попытке выполнить

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

Падает из-за обращения к памяти, ранее принадлежавшей выгруженной библиотеке. Если QBuffer будет хранить копию — ничего не должно падать...
Re[4]: Программно изменить коментрарии к версии
От: Аноним  
Дата: 24.08.06 08:49
Оценка:
Здравствуйте, McQwerty, Вы писали:

S>>Возникло несколько вопросов.

S>>1. Что за класс базовый класс VObject у VVersionInfo и VCommonVersionInfo?
MQ>Обычный базовый класс "всего". Можно игнорировать...
S>>2. Не понятнно что тип QBuffer у переменной VCommonVersionInfo::m_Value. Я реализовал этот тип так
MQ>Это просто буфер на н-цать байт. В отличии от восстановленного варианта содержит копию данных
S>>
MQ>    class QBuffer
MQ>    {
MQ>    public:
MQ>        QBuffer ();
MQ>        QBuffer (DWORD dwSize);
MQ>        QBuffer (QBuffer& aBuffer);
MQ>        QBuffer (LPBYTE lpData, DWORD dwSize);
MQ>        virtual ~QBuffer ();

MQ>    public:
MQ>        VOID Allocate (DWORD dwSize);
MQ>        VOID Assign (LPBYTE lpData, DWORD dwSize);
MQ>        VOID Set (LPBYTE lpData, DWORD dwSize);

MQ>    public:
MQ>        LPBYTE Get () const;
MQ>        DWORD Size () const;

MQ>    protected:
MQ>        VOID allocate (LPBYTE lpData, DWORD dwSize);
MQ>        VOID deallocate ();
MQ>        VOID initialize ();

MQ>    private:
MQ>        LPBYTE lpBuffer;
MQ>        DWORD dwBufferSize;
MQ>    }; // QBuffer


MQ>VOID QBuffer::initialize ()
MQ>{
MQ>    lpBuffer = NULL;
MQ>    dwBufferSize = 0;
MQ>} // QBuffer::initialize

MQ>QBuffer::QBuffer ()
MQ>{
MQ>    initialize ();
MQ>    allocate (NULL, 0);
MQ>} // QBuffer::QBuffer

MQ>QBuffer::QBuffer (DWORD dwSize)
MQ>{
MQ>    initialize ();
MQ>    allocate (NULL, dwSize);
MQ>} // QBuffer::QBuffer

MQ>QBuffer::QBuffer (QBuffer& aBuffer)
MQ>{
MQ>    initialize ();
MQ>    allocate (aBuffer. Get (), aBuffer. Size ());
MQ>} // QBuffer::QBuffer

MQ>QBuffer::QBuffer (LPBYTE lpData, DWORD dwSize)
MQ>{
MQ>    initialize ();
MQ>    allocate (lpData, dwSize);
MQ>} // QBuffer::QBuffer

MQ>QBuffer::~QBuffer ()
MQ>{
MQ>    deallocate ();
MQ>} // QBuffer::~QBuffer

MQ>VOID QBuffer::allocate (LPBYTE lpData, DWORD dwSize)
MQ>{
MQ>    deallocate ();

MQ>    if (dwSize)
MQ>    {
MQ>        lpBuffer = (LPBYTE) GlobalAlloc (GPTR, dwSize);

MQ>        if (lpBuffer)
MQ>        {
MQ>            if (lpData)
MQ>                CopyMemory (lpBuffer, lpData, dwSize);

MQ>            dwBufferSize = dwSize;
MQ>        }
MQ>        else
MQ>            dwBufferSize = 0;
MQ>    }
MQ>} // QBuffer::allocate

MQ>VOID QBuffer::deallocate ()
MQ>{
MQ>    if (lpBuffer)
MQ>    {
MQ>        GlobalFree ((HGLOBAL) lpBuffer);
MQ>        lpBuffer = NULL;
MQ>    }

MQ>    dwBufferSize = 0;

MQ>    initialize ();
MQ>} // QBuffer::deallocate

MQ>LPBYTE QBuffer::Get () const { return lpBuffer; }
MQ>DWORD QBuffer::Size () const { return dwBufferSize; }

MQ>VOID QBuffer::Allocate (DWORD dwSize)
MQ>{
MQ>    allocate (NULL, dwSize);
MQ>} // QBuffer::Allocate

MQ>VOID QBuffer::Assign (LPBYTE lpData, DWORD dwSize)
MQ>{
MQ>    allocate (lpData, dwSize);
MQ>} // QBuffer::Assign

MQ>VOID QBuffer::Set (LPBYTE lpData, DWORD dwSize)
MQ>{
MQ>    deallocate ();
MQ>    lpBuffer = lpData;
MQ>    dwBufferSize = dwSize;
MQ>} // QBuffer::Set
S>>

S>>3. Не знаю что такое VArray поэтому вместо
S>> typedef VArray <VVersionInfo*> VChilds;
S>> использовал vector из STL
S>> typedef std::vector<VVersionInfo*> VChilds;
S>> Надеюсь это тоже не отразилось на функциональности
MQ>Вполне подойдёт...

S>>4. Для того что бы заработало дополнил ваш код из примера.


S>> При этом при попытке выполнить

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

MQ>Падает из-за обращения к памяти, ранее принадлежавшей выгруженной библиотеке. Если QBuffer будет хранить копию — ничего не должно падать...


У Вас есть функции для замены.
А как добавить новый комментарий к версии файла?
Существует ли реализация этой футкции?
Если есть сообщите пожалуйста.
Re[5]: Программно изменить коментрарии к версии
От: McQwerty Россия  
Дата: 25.08.06 13:50
Оценка:
А>У Вас есть функции для замены.
А>А как добавить новый комментарий к версии файла?
А>Существует ли реализация этой футкции?
А>Если есть сообщите пожалуйста.

Да. Это возможно.
Все строки, которые будут записаны в ресурсы, содержатся в массиве m_Childs
класса VVersionInfo. Соответственно, если в этот массив добавить ещё один
элемент, то при выполнении функции Compile, он будет добавлен в ресурсы.

Сделать это можно примерно так:
VVersionInfo ver (pVer);
ver. m_Childs. Add (new VVersionInfo ("NewStr", "NewVal"));

Конструктор от двух строк для VVersionInfo придётся добавить самому — у
меня его нет.
Re[6]: Программно изменить коментрарии к версии
От: Аноним  
Дата: 30.08.06 06:31
Оценка:
Здравствуйте, McQwerty, Вы писали:

А>>У Вас есть функции для замены.

А>>А как добавить новый комментарий к версии файла?
А>>Существует ли реализация этой футкции?
А>>Если есть сообщите пожалуйста.

MQ>Да. Это возможно.

MQ>Все строки, которые будут записаны в ресурсы, содержатся в массиве m_Childs
MQ>класса VVersionInfo. Соответственно, если в этот массив добавить ещё один
MQ>элемент, то при выполнении функции Compile, он будет добавлен в ресурсы.

MQ>Сделать это можно примерно так:

MQ>VVersionInfo ver (pVer);
MQ>ver. m_Childs. Add (new VVersionInfo ("NewStr", "NewVal"));

MQ>Конструктор от двух строк для VVersionInfo придётся добавить самому — у

MQ>меня его нет.

Спасибо за ответ.

Коструктор VVersionInfo имеет следующую реализацию

VVersionInfo::VVersionInfo (const LPVOID pMemoryLocation, DWORD nLevel)
{
    LPBYTE pTemp = (LPBYTE) pMemoryLocation;
    m_pInfo = new VCommonVersionInfo (pMemoryLocation, nLevel);
    INT dwSizeRest = m_pInfo -> ChildSize ();
    pTemp += m_pInfo -> Size ();

    while (dwSizeRest > 0)
    {
        VVersionInfo* pChild = new VVersionInfo (pTemp, nLevel + 1);
        m_Childs. push_back (pChild);
        DWORD dwItemSize = pChild -> Size ();
        pTemp += dwItemSize;
        dwSizeRest -= dwItemSize;

        if (dwSizeRest < 0)
        {
            dwSizeRest = 0;
        }
    }
} // VVersionInfo::VVersionInfo


я попробовал сделать еще один конструктор


VVersionInfo::VVersionInfo (LPWSTR m_pszKey ,LPWSTR m_psValue,  DWORD nLevel)
{
    m_pInfo = new VCommonVersionInfo (m_pszKey,m_psValue, nLevel);
    INT dwSizeRest = m_pInfo -> ChildSize ();
}


VVersionInfo::VCommonVersionInfo::VCommonVersionInfo (LPWSTR pszKey, LPWSTR pszValue,DWORD nLevel)
{
   
    //const LPBYTE pTemp = (LPBYTE) pMemoryLocation;

    m_nSize = 0;
    m_nLevel = nLevel;

    m_wLength = (wcslen (pszKey) + 1) + (wcslen (pszValue) + 1);
    m_nSize += sizeof (WORD);
    m_wValueLength = (wcslen (pszValue) + 1);   
    m_nSize += sizeof (WORD);
    m_wType =  1;  //string data         
    m_nSize += sizeof (WORD);

    //m_wLength = * ((LPWORD) (pTemp + m_nSize));
    //m_nSize += sizeof (WORD);
    //m_wValueLength = * ((LPWORD) (pTemp + m_nSize));   
    //m_nSize += sizeof (WORD);
    //m_wType =  * ((LPWORD) (pTemp + m_nSize));           
    //m_nSize += sizeof (WORD);

    m_pszKey = pszKey;
    m_nSize += (wcslen (m_pszKey) + 1) * sizeof (WCHAR);

    m_nSize += (4 - m_nSize) & 3;    // âûðàâíèâàíèå íà 32 áèòà

    DWORD dwFactor = (m_nLevel == 3) ? sizeof (WORD) : 1;
    m_Value. Assign ((LPBYTE)pszValue,wcslen (pszValue) + 1);
    m_nSize += m_wValueLength * dwFactor;
   
    m_nSize += (4 - m_nSize) & 3;    // âûðàâíèâàíèå íà 32 áèòà
   
} // VVersionInfo::VCommonVersionInfo::VCommonVersionInfo


и

VVersionInfo* verN=new VVersionInfo(L"SNP",L" 1.20.0",2);
ver.m_Childs.push_back(verN);
Но в такой реализации не работает.

Вопрос в следующем:
какого должно быть значение nLevel
и какие значения должны принимать члены класса VCommonVersionInfo в такой реализации.

Буду очень признателен за помощь.

Алексан.
Re[7]: Программно изменить коментрарии к версии
От: Аноним  
Дата: 17.04.09 10:14
Оценка:
А как себя программа поведет, если кол-во символов совпадает в строке или меньше существующей?
Re: Программно изменить коментрарии к версии
От: bnk СССР http://unmanagedvisio.com/
Дата: 18.04.09 08:54
Оценка:
Здравствуйте, stepaster, Вы писали:

S>Существует готовый exe файл. Нужно в ресурсе version этого файла программно изменить коментарии (пункт Comments). Пробовал способо описанным здесь http://www.codeproject.com/samples/UpdateVersion.asp не получилось, exe-шник перестает запускаться после внесения изменений.


Если цель состоит в том, чтобы просто програмно (из скрипта например) изменить информацию о версии (комментарий) в экзешнике,
а не написать собственную программу, которая это делает, то IMHO намного проще будет ResHack использовать...
Все делается из командной строки.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.