Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Нужна помощь по работе с ресурсами (конкретно 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


Наверх

Титульная страница Поиск, карта сайта Написать письмо