How to access the version of an .exe file with PHP?

5

I need to access the property called "version" in my file, and I know this is not possible in Javascript, but I do not know which language to use, or what to do to get to it. I thought about using PHP, but I do not have much knowledge in this area, could you help me?

    
asked by anonymous 19.09.2017 / 21:57

2 answers

2
  

WARNING: All codes in this reply have been written by third parties and have not been tested by me. Beware of using them.

In Stack Overflow in English you have a similar question , and user Toni posted the following code there:

<?php
function GetFileVersion($FileName) {

    $handle=fopen($FileName,'rb');
    if (!$handle) return FALSE;
    $Header=fread ($handle,64);
    if (substr($Header,0,2)!='MZ') return FALSE;
    $PEOffset=unpack("V",substr($Header,60,4));
    if ($PEOffset[1]<64) return FALSE;
    fseek($handle,$PEOffset[1],SEEK_SET);
    $Header=fread ($handle,24);
    if (substr($Header,0,2)!='PE') return FALSE;
    $Machine=unpack("v",substr($Header,4,2));
    if ($Machine[1]!=332) return FALSE;
    $NoSections=unpack("v",substr($Header,6,2));
    $OptHdrSize=unpack("v",substr($Header,20,2));
    fseek($handle,$OptHdrSize[1],SEEK_CUR);
    $ResFound=FALSE;
    for ($x=0;$x<$NoSections[1];$x++) {      //$x fixed here
        $SecHdr=fread($handle,40);
        if (substr($SecHdr,0,5)=='.rsrc') {         //resource section
            $ResFound=TRUE;
            break;
        }
    }
    if (!$ResFound) return FALSE;
    $InfoVirt=unpack("V",substr($SecHdr,12,4));
    $InfoSize=unpack("V",substr($SecHdr,16,4));
    $InfoOff=unpack("V",substr($SecHdr,20,4));
    fseek($handle,$InfoOff[1],SEEK_SET);
    $Info=fread($handle,$InfoSize[1]);
    $NumDirs=unpack("v",substr($Info,14,2));
    $InfoFound=FALSE;
    for ($x=0;$x<$NumDirs[1];$x++) {
        $Type=unpack("V",substr($Info,($x*8)+16,4));
        if($Type[1]==16) {             //FILEINFO resource
            $InfoFound=TRUE;
            $SubOff=unpack("V",substr($Info,($x*8)+20,4));
            break;
        }
    }
    if (!$InfoFound) return FALSE;
    $SubOff[1]&=0x7fffffff;
    $InfoOff=unpack("V",substr($Info,$SubOff[1]+20,4)); //offset of first FILEINFO
    $InfoOff[1]&=0x7fffffff;
    $InfoOff=unpack("V",substr($Info,$InfoOff[1]+20,4));    //offset to data
    $DataOff=unpack("V",substr($Info,$InfoOff[1],4));
    $DataSize=unpack("V",substr($Info,$InfoOff[1]+4,4));
    $CodePage=unpack("V",substr($Info,$InfoOff[1]+8,4));
    $DataOff[1]-=$InfoVirt[1];
    $Version=unpack("v4",substr($Info,$DataOff[1]+48,8));
    $x=$Version[2];
    $Version[2]=$Version[1];
    $Version[1]=$x;
    $x=$Version[4];
    $Version[4]=$Version[3];
    $Version[3]=$x;
    return $Version;
}

I have not tested this code, and I found it very bad to read, which is not a good sign. But maybe it will solve your problem.

Perhaps Scott Bartgis's user code is better - at least it's cleaner, but I have not tested it either:

<?php
function get_product_version($file_name)
{
   $key = "P\x00r\x00o\x00d\x00u\x00c\x00t\x00V\x00e\x00r\x00s\x00i\x00o\x00n\x00\x00\x00";
   $fptr = fopen($file_name, "rb");
   $data = "";
   while (!feof($fptr))
   {
      $data .= fread($fptr, 65536);
      if (strpos($data, $key)!==FALSE)
         break;
      $data = substr($data, strlen($data)-strlen($key));
   }
   fclose($fptr);
   if (strpos($data, $key)===FALSE)
      return "";
   $pos = strpos($data, $key)+strlen($key);
   $version = "";
   for ($i=$pos; $data[$i]!="\x00"; $i+=2)
      $version .= $data[$i];
   return $version;
}

echo get_product_version("/path_to_file/foo.exe");
?>

A third option that seems feasible: In Windows environments, you can get an EXE version by creating a FileSystemObject via COM extension.

    
20.09.2017 / 21:55
2

I found this answer in SOen that looks very good, however no I can state that will work in all environments, anyway the code returns a lot thing:

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,"
echo "<pre>".print_r( getFileVersionInfo('notepad.exe'), true)."</pre>";
echo "<pre>".print_r( getFileVersionInfo('jre-7u9-windows-x64.exe'), true)."</pre>";
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
)
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
)
",$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; } } }

The examples:

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,"
echo "<pre>".print_r( getFileVersionInfo('notepad.exe'), true)."</pre>";
echo "<pre>".print_r( getFileVersionInfo('jre-7u9-windows-x64.exe'), true)."</pre>";
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
)
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
)
",$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; } } }

Return:

notepad.exe (32-bit):

%pre%

jre-7u9-windows-x64.exe (64-bit): %pre%     

20.09.2017 / 22:04