В файлах Windows EXE есть метаданные типа CompanyName
, FileVersion
, InternalName
, ProductName
, OriginalFileName
, ProductVersion
и т. Д.
Как я могу извлечь такие метаданные из PHP?
Мне стало интересно, поэтому я решил написать эту функцию:
function getFileVersionInfo($filename,$encoding='UTF-8'){ $dat = file_get_contents($filename); if($pos=strpos($dat,mb_convert_encoding('VS_VERSION_INFO','UTF-16LE'))){ $pos-= 6; $six = unpack('v*',substr($dat,$pos,6)); $dat = substr($dat,$pos,$six[1]); if($pos=strpos($dat,mb_convert_encoding('StringFileInfo','UTF-16LE'))){ $pos+= 54; $res = []; $six = unpack('v*',substr($dat,$pos,6)); while($six[2]){ $nul = strpos($dat,"\0\0\0",$pos+6)+1; $key = mb_convert_encoding(substr($dat,$pos+6,$nul-$pos-6),$encoding,'UTF-16LE'); $val = mb_convert_encoding(substr($dat,ceil(($nul+2)/4)*4,$six[2]*2-2),$encoding,'UTF-16LE'); $res[$key] = $val; $pos+= ceil($six[1]/4)*4; $six = unpack('v*',substr($dat,$pos,6)); } return $res; } } }
вfunction getFileVersionInfo($filename,$encoding='UTF-8'){ $dat = file_get_contents($filename); if($pos=strpos($dat,mb_convert_encoding('VS_VERSION_INFO','UTF-16LE'))){ $pos-= 6; $six = unpack('v*',substr($dat,$pos,6)); $dat = substr($dat,$pos,$six[1]); if($pos=strpos($dat,mb_convert_encoding('StringFileInfo','UTF-16LE'))){ $pos+= 54; $res = []; $six = unpack('v*',substr($dat,$pos,6)); while($six[2]){ $nul = strpos($dat,"\0\0\0",$pos+6)+1; $key = mb_convert_encoding(substr($dat,$pos+6,$nul-$pos-6),$encoding,'UTF-16LE'); $val = mb_convert_encoding(substr($dat,ceil(($nul+2)/4)*4,$six[2]*2-2),$encoding,'UTF-16LE'); $res[$key] = $val; $pos+= ceil($six[1]/4)*4; $six = unpack('v*',substr($dat,$pos,6)); } return $res; } } }
Он работает с 32-битным и 64-битным exe. Пример использования:
echo "<pre>".print_r(getFileVersionInfo('notepad.exe'),1)."</pre>"; echo "<pre>".print_r(getFileVersionInfo('php.exe'),1)."</pre>"; echo "<pre>".print_r(getFileVersionInfo('jre-7u9-windows-x64.exe'),1)."</pre>";
notepad.exe (32-бит):
Array ( [CompanyName] => Microsoft Corporation [FileDescription] => Notepad [FileVersion] => 6.1.7600.16385 (win7_rtm.090713-1255) [InternalName] => Notepad [LegalCopyright] => © Microsoft Corporation. All rights reserved. [OriginalFilename] => NOTEPAD.EXE [ProductName] => Microsoft® Windows® Operating System [ProductVersion] => 6.1.7600.16385 )
php.exe (32-бит):
Array ( [Comments] => Thanks to Edin Kadribasic, Marcus Boerger, Johannes Schlueter, Moriyoshi Koizumi, Xinchen Hui [CompanyName] => The PHP Group [FileDescription] => CLI [FileVersion] => 7.0.12 [InternalName] => CLI SAPI [LegalCopyright] => Copyright © 1997-2016 The PHP Group [LegalTrademarks] => PHP [OriginalFilename] => php.exe [ProductName] => PHP [ProductVersion] => 7.0.12 [URL] => http://www.php.net )
jre-7u9-windows-x64.exe (64-разрядная версия):
Array ( [CompanyName] => Oracle Corporation [FileDescription] => Java(TM) Platform SE binary [FileVersion] => 7.0.90.5 [Full Version] => 1.7.0_09-b05 [InternalName] => Setup Launcher [LegalCopyright] => Copyright © 2012 [OriginalFilename] => jinstall.exe [ProductName] => Java(TM) Platform SE 7 U9 [ProductVersion] => 7.0.90.5 )
Что-то интересное в php.exe
: Comments
и URL
не отображаются на вкладке «Сведения». По крайней мере, на моем компьютере.
Наслаждаться.
Обновление 1: я забыл проверить ошибки. Теперь он возвращает null, если информация о версии не существует.
Обновление 2: Большое спасибо @Abela за то, что привлекли внимание к проблеме кодирования.
Я добавил необязательный второй параметр, который по умолчанию соответствует UTF-8, который должен работать для большинства целей. Если вам нужен однобайтовый вывод, используйте вместо этого ISO-8859-1:
getFileVersionInfo('php.exe','ISO-8859-1');