Здравствуйте, 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 то он не запускается.