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

Asked

Viewed 165 times

5

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

  • Your server is windows or linux?

  • It’s the one offered by the hostgator

  • Only eCHEF_x64.exe has no js file

2 answers

2

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

No Stack Overflow in English has a similar question, and user Toni posted there the following code:

<?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 did not test this code, and I found it very bad to read, which is not a good sign. But maybe it solves your problem.

Maybe user code Scott Bartgis is better - at least it’s cleaner, but I haven’t 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, it is possible to get the version of an EXE by creating a FileSystemObject via extension WITH.

  • 1

    The Return could be null to be more intuitive that the app has not marked the version via "winver" :) - Just suggestion, I understand that it is 3rd and that there are no guarantees.

2

I found this answer in Soen which looks very good, however nay I can say that it will work in all environments, anyway the code returns enough 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,"\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;
        }
    }
}

The examples:

echo "<pre>".print_r( getFileVersionInfo('notepad.exe'), true)."</pre>";
echo "<pre>".print_r( getFileVersionInfo('jre-7u9-windows-x64.exe'), true)."</pre>";

Return:

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
)

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
)
  • I really found very good your code, however I need to check the file in a bank, you could explain me how to implement your code to this need?

  • @Alis depends, checking a file in a database is very ambiguous, I have no idea how this your database. Binary data from . exe are in a column in the table or the database only contains the path of . exe? Is using what mysql, oracle, sqlserver, sqlite? And what PDO api, mysqli? Besides, this question of yours now kind of invalidates the actual answers. Anyway I’ll try to help you, as long as you answer what I asked above.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.