![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужна помощь по работе с ресурсами (конкретно RT_VERSION) [D7, WinXP]
WanderBuild © (2009-01-12 15:18:00)Здравствуйте! Возникла необходимость вытащить информацию о версии и вообще весь блок RT_VERSION из произвольного файла в таком духе:
Version language : Русский
CompanyName : Корпорация Майкрософт
FileDescription : Громкость
FileVersion : 5.1.2600.0 (xpclient.010817-1148)
InternalName : sndvol32.exe
LegalCopyright : © Корпорация Майкрософт. Все права защищены.
OriginalFilename : sndvol32.exe
ProductName : Операционная система Microsoft® Windows®
ProductVersion : 5.1.2600.0
В сети нашел 2 примера, и оба не удовлетворяют моей потребности, а мозгов довести до ума как назло не хватает :(
Вот первый пример:
function GetFMetadata(FName: String): String;
const
InfoNum = 10;
InfoStr: array[1..InfoNum] of string = ('CompanyName', 'FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'LegalTradeMarks', 'OriginalFileName', 'ProductName', 'ProductVersion', 'Comments');
var
n, Len, i: DWORD;
Buf: PChar;
TableName, Value: PChar;
begin
n := GetFileVersionInfoSize(PChar(FName), n);
if n > 0 then
begin
Buf := AllocMem(n);
for i := 1 to InfoNum do
PChar('\StringFileInfo\040904E4\'+InfoStr[i])
if VerQueryValue(Buf, PChar('\StringFileInfo\'+TableName+'\'+InfoStr[i]),
Pointer(Value), Len) then
Writeln(InfoStr[i] + ' = ' + Value);
FreeMem(Buf, n);
end
else
Writeln('No version information found');
end;
Что не нравится в нем:
1. Самое главное то, что в строке
\StringFileInfo\040904E4\
Последняя, числовая группа изменяется, по всей видимости в зависимости от языка приложения, т.е. в англоязычной программе это 040904E4, в то время как в русской, это 041904E3, а если программа на другом языке... ну в общем бред
2. То, что имена ресурсов заданы в перечислении, как-то лишено элегантности, ведь все эти имена однозначно есть непосредственно в ресурсе, мне нужно достать ВСЮ таблицу, как в примере (см. выше)
И вот пример 2:
function GetFileVersion(FName:String): String;
var
pVer : ^VS_FIXEDFILEINFO;
Buff : Pointer;
iVer : DWORD;
i : Integer;
hModule: THandle;
begin
hModule := LoadLibraryEx(PChar(FName), 0, LOAD_LIBRARY_AS_DATAFILE);
if hModule <> 0 then
try
iVer := FindResource(hModule,'#1', RT_VERSION);
if iVer = 0 then Result := '<Unknown>'
else
Begin
Buff := Pointer(LoadResource(hModule, iVer));
pVer := NIL;
for i := 0 to (WORD(Buff^) DIV 4)-1 do
begin
if DWORD ( Buff^ ) = $FEEF04BD then
begin
pVer := Buff;
Break;
end;
Buff := Ptr(DWORD(Buff)+4);
end;
if pVer^.dwSignature <> $FEEF04BD then Result := '<Unknown>'
else
Result := Format('%d.%d.%d.%d)',
[(pVer^.dwProductVersionMS SHR $10) AND $FFFF,
pVer^.dwProductVersionMS AND $FFFF,
(pVer^.dwProductVersionLS SHR $10) AND $FFFF,
pVer^.dwProductVersionLS AND $FFFF]);
End;
finally
FreeLibrary(hModule);
end;
end;
Для того, чтобы открыть произвольный файл я его доработал, и код тут выглядит уже не так ламерски, как в первом, однако кроме версии файла больше вытащить ничего не могу, битый час бился, это выше моего понимания видимо :(
Ребята, помогите пожалуйста доработать второй пример или подскажите ссылочку, может у кого уже есть нечто подобное.
Заранее, большое спасибо!
KilkennyCat (2009-01-16 14:45:00) [1]http://msdn.microsoft.com/en-us/library/aa381058.aspx
KilkennyCat (2009-01-16 14:42:00) [2]http://msdn.microsoft.com/en-us/library/ms646981(VS.85).aspx