PHP ile exe Sürüm alın

4 Cevap

Php ile olası bir exe sürümünü almak mı? Ben indirilebilir bir dosya sürümünü yazdırmak istiyorum ...

Windows exe ve php linux sunucu üzerinde çalışan

4 Cevap

I wanted the same thing, so I coded this: It returns FALSE, if it can't get the version info, or an ARRAY of four elements with file version fields (numbers, which are separated by .) It works only for 32-bit PE files (as I had no need for other formats).

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++) {
    $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;

}

On a win32 machine you can use the COM extension and FileSystemObject.GetFileVersion() method to retrieve the version info. e.g.

$path = getenv('SystemRoot').'\\NOTEPAD.EXE';
$fso = new COM('Scripting.FileSystemObject');
echo $path, ' : ', $fso->GetFileVersion($path);

baskılar (benim makinede) C:\WINDOWS\NOTEPAD.EXE : 5.1.2600.5512

Geçenlerde Windows'tan Linux'a bizim hosting taşındı. Bu, Microsoft nesneleri verilen VBScript ile yapmak oldukça kolay oldu, ama Linux ve PHP ben bir şey bulamadı. Biz. Exe dosya taramak ve bir VB.Net uygulama içinde olduğunu "Ürün Sürümü" ayıklamak için PHP bu işlevi yazdı. Eğer versiyon bilgisi ve boş terminatör olduğunu bulmak ne olursa olsun dize olması $ anahtarını değiştirebilirsiniz.

Bu $ anahtar dizesi arıyor 64k parçalar dosyaları tarar unutmayın. Büyük bir. Exe varsa, bir kaç saniye sürebilir. Neredeyse anlık yani benim. Exe 52k olduğunu. Eğer büyük bir exe varsa, tarama değiştirebilirsiniz.

<?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");
?>

Ben Windows üzerinde değiliz varsayarak yaşıyorum, ve Windows çalıştırılabilir saklanabilir Sürüm bilgi anlamına ve Windows Explorer gibi bir dosya için iletişim özellikleri açılır.

Bu bilgiler (örneğin, this question bakınız) yürütülebilir VS_VERSION_INFO blokta depolanmış olan gibi görünmektedir. Ben bile Windows kendisi üzerinde, basit bir şekilde bu bilgileri ayıklar herhangi bir alet bilmiyorum.

Orada (here Perl örneğe bakın) Windows API üzerinden bu bilgileri ele almak için çeşitli yollar gibi görünüyor ama sadece yürütülebilir ayrıştırma tarafından "sıfırdan" çalışan herhangi bir yaklaşım göremiyorum.

Eğer biraz etrafında kazmak ise, bir EXE dosyasından VS_VERSION_INFO bilgi almak için nasıl açıklayan bir dosya biçimi açıklamasını bulmak mümkün olabilir. Bu olsa, güvenilir işe almak için bir sürü iş için hazırlıklı olun.

Bunu yapmak istiyorsanız, zaman ve çaba yatırım yapmaya hazır olun.