Extract internal EXE info

前端 未结 1 1071
悲&欢浪女
悲&欢浪女 2021-02-10 14:01

Windows EXE files have some metadata like CompanyName, FileVersion, InternalName, ProductName, OriginalFileName,

1条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-10 14:43

    I got curious about this, so I decided to write this function:

    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;
            }
        }
    }
    

    It works with 32-bit and 64-bit exe. Usage example:

    echo "
    ".print_r(getFileVersionInfo('notepad.exe'),1)."
    "; echo "
    ".print_r(getFileVersionInfo('php.exe'),1)."
    "; echo "
    ".print_r(getFileVersionInfo('jre-7u9-windows-x64.exe'),1)."
    ";

    notepad.exe (32-bit):

    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-bit):

    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-bit):

    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
    )
    

    Something interesting about php.exe: the Comments and URL don't show up in the Details tab. At least in my computer.

    Enjoy.

    Update 1: I forgot error checking. Now it returns null if the version info doesn't exist.

    Update 2: Many thanks to @Abela for bringing an encoding issue to my attention.

    I added an optional 2nd parameter that defaults to UTF-8 which should work for most purposes. If you need single-byte-character output, use ISO-8859-1 instead, like this:

    getFileVersionInfo('php.exe','ISO-8859-1');
    

    0 讨论(0)
提交回复
热议问题