PDA

View Full Version : گرفتن File Vesrion فایل



loo30fer
پنج شنبه 15 اردیبهشت 1390, 09:57 صبح
با سلام خدمت همه دوستان خوب
میخواستم بدونم چطور میتونم File Vesrion یک فایل رو بدست بیارم نمیخوام از رجیستری کمک بگیرم بلکه همون File Vesrion رو که در تب Vesrion قرار داره رو بگیرم ممنون میشم تمامی راهها رو پیشنهاد کنید و بنده رو راهنمایی کنید , جواب این سوال خیلی برام مهمه با تشکر.

vcldeveloper
پنج شنبه 15 اردیبهشت 1390, 11:42 صبح
نمیخوام از رجیستری کمک بگیرم
اگر هم میخواستید؛ رجیستری کمک خاصی برای به دست آوردن ورژن فایل ها بهتون نمی کرد.


چطور میتونم File Vesrion یک فایل رو بدست بیارم


class function GetFileVersion(const FileName: TFileName): string;
var
lpdwHandle,
puLen,
VersionInfoSize : Cardinal;
lpData,
lplpBuffer : pointer;
begin
Result := '';
if not FileExists(FileName) then
raise Exception.Create('File not found');
//Get version information size
VersionInfoSize := GetFileVersionInfoSize(PChar(FileName),lpdwHandle) ;
if VersionInfoSize <= 0 then
raise Exception.Create('Could not retreive file version info');
//Get memory for the version information
GetMem(lpData,VersionInfoSize);
try
//Retrieve version information
if not GetFileVersionInfo(PChar(FileName),0,VersionInfoSi ze,lpData) then
RaiseLastOSError;
//Extract English file version from the buffer
if not VerQueryValue(lpData,'\\StringFileInfo\\040904E4\\ FileVersion',lplpBuffer,puLen) then
RaiseLastOSError;
finally
FreeMem(lpData);
end;
//If any file version info is retrieved then return it as the function result.
if puLen > 0 then
Result := Trim(PChar(lplpBuffer));
end;

دقت کنید که این کد ورژن رو از روی resource انگلیسی برنامه میخونه، اگر resource ایی با زبان انگلیسی حاوی اطلاعات ورژن فایل موجود نباشه، خطا برگشت میده. اگر ریسورس های برنامه تون با زبانی غیر از انگلیسی ذخیره شدند، باید اون مقدار 040904E4 را متناسب با زبان مورد نظر تغییر بدید.

loo30fer
پنج شنبه 15 اردیبهشت 1390, 13:35 عصر
ممنون جناب کشاورز
یک نگاهی به این کد بندازین ببینید تو برنامه درست ازش استفاده کردم و در هنگام خواندن هم RaiseLastOSError رو میده که حتما همونطور که گفتین میتونه به خاطر این باشه که resource انگلیسی نباشه.

class function GetFileVersion(const FileName: TFileName): string;
var
lpdwHandle,puLen,VersionInfoSize : Cardinal;
lpData,lplpBuffer : pointer;
begin
Result := '';
if not FileExists(FileName) then
raise Exception.Create('File not found');
VersionInfoSize := GetFileVersionInfoSize(PChar(FileName),lpdwHandle) ;
if VersionInfoSize <= 0 then
raise Exception.Create('Could not retreive file version info');
GetMem(lpData,VersionInfoSize);
try
if not GetFileVersionInfo(PChar(FileName),0,VersionInfoSi ze,lpData) then
RaiseLastOSError;
if not VerQueryValue(lpData,'\\StringFileInfo\\040904E4\\ FileVersion',lplpBuffer,puLen) then
RaiseLastOSError;
finally
FreeMem(lpData);
end;
if puLen > 0 then
Result := Trim(PChar(lplpBuffer));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetFileVersion('C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe');
end;
حالا چند مشکل دارم :
1- چطور میتونم زبان استفاده شده resource رو متوجه بشم و همینطور کدزبانش رو بگیرم ؟
2- چطور میتونم ورژن بدست آمده رو تو پیغام نمایش بدم.
بازم ازتون تشکر میکنم جناب کشاورز.

loo30fer
جمعه 16 اردیبهشت 1390, 00:35 صبح
ممنون مشکل حل شد.

loo30fer
جمعه 16 اردیبهشت 1390, 11:06 صبح
جناب کشاورز همونطور که گفتم مشکل حل شد فقط برای اینکه بخوام Product Name فایل رو هم بگیرم باید چه توابعی رو تو کدی که قرار دادین تغییر بدم تا بتونم اینکار رو انجام بدم ؟ با تشکر.

Felony
شنبه 17 اردیبهشت 1390, 04:34 صبح
یک Record به صورت زیر تعریف کنید :

type
TEXEVersionData = record
CompanyName,
FileDescription,
FileVersion,
InternalName,
LegalCopyright,
LegalTrademarks,
OriginalFileName,
ProductName,
ProductVersion,
Comments,
PrivateBuild,
SpecialBuild: string;
end;

تابع زیر رو هم در برنامه بنویسید :


function GetEXEVersionData(const FileName: string): TEXEVersionData;
type
PLandCodepage = ^TLandCodepage;
TLandCodepage = record
wLanguage,
wCodePage: word;
end;
var
dummy,
len: cardinal;
buf, pntr: pointer;
lang: string;
begin
len := GetFileVersionInfoSize(PChar(FileName), dummy);
if len = 0 then
RaiseLastOSError;
GetMem(buf, len);
try
if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then
RaiseLastOSError;

if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then
RaiseLastOSError;

lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]);

if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then
result.CompanyName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileDescription'), pntr, len){ and (@len <> nil)} then
result.FileDescription := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileVersion'), pntr, len){ and (@len <> nil)} then
result.FileVersion := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\InternalName'), pntr, len){ and (@len <> nil)} then
result.InternalName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalCopyright'), pntr, len){ and (@len <> nil)} then
result.LegalCopyright := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalTrademarks'), pntr, len){ and (@len <> nil)} then
result.LegalTrademarks := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\OriginalFileName'), pntr, len){ and (@len <> nil)} then
result.OriginalFileName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductName'), pntr, len){ and (@len <> nil)} then
result.ProductName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductVersion'), pntr, len){ and (@len <> nil)} then
result.ProductVersion := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\Comments'), pntr, len){ and (@len <> nil)} then
result.Comments := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\PrivateBuild'), pntr, len){ and (@len <> nil)} then
result.PrivateBuild := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\SpecialBuild'), pntr, len){ and (@len <> nil)} then
result.SpecialBuild := PChar(pntr);
finally
FreeMem(buf);
end;
end;

و به صورت زیر ازش استفاده کنید :

var
Data: TEXEVersionData;
begin
Data:= GetEXEVersionData('FileName');
with Memo1.Lines do
begin
Add('CompanyName : ' + Data.CompanyName);
Add('FileDescription : ' + Data.FileDescription);
Add('FileVersion : ' + Data.FileVersion);
Add('InternalName : ' + Data.InternalName);
Add('LegalCopyright : ' + Data.LegalCopyright);
Add('LegalTrademarks :' + Data.LegalTrademarks);
Add('OriginalFileName : ' + Data.OriginalFileName);
Add('ProductName : ' + Data.ProductName);
Add('ProductVersion : ' + Data.ProductVersion);
Add('Comments : ' + Data.Comments);
Add('PrivateBuild : ' + Data.PrivateBuild);
Add('SpecialBuild : ' + Data.SpecialBuild);
end;
end;

loo30fer
شنبه 17 اردیبهشت 1390, 08:25 صبح
خیلی خیلی ممنون جناب تاجیک , اگه امکان داره درباره تابع و Record هم توضیح بدین ممنون میشم میخوام نحوه کارش رو بدونم تا از کدنویسیش بتونم سر در بیارم که چطور عمل میکنه و راستی این تابع تنها برای ریسورس انگلیسی عمل میکنه ؟

loo30fer
شنبه 17 اردیبهشت 1390, 08:48 صبح
یک سوال دیگه هم داشتم من اگه بخوام این کد رو تو تمامی دکمه ها ازش استفاده کنم (مثلا 10تا دکمه) بهتره متغیر Data رو تو فرم تعریف کنم یا توی هردکمه تا حجم اشغالی تو رم بالا نره ؟

loo30fer
یک شنبه 18 اردیبهشت 1390, 22:45 عصر
من این قسمتهایی رو که اگه ریسورس زبان انگلیسی نباشه یا آدرس رو اشتباه بدیم خطا میگیره رو برای جلوگیری از پیغام خطا خودم براش تعریف کردم تا مثلا پیغام من رو نشون بده ولی باز اول پیغام من رو نشون میده بعد باز پیغام خطای مربوطه کد رو قرار دادم ممنون میشم بگین مشکل از کجاست و چطور باید براش تعریف کنم ؟ با تشکر.
function GetEXEVersionData(const FileName: string): TEXEVersionData;
type
PLandCodepage = ^TLandCodepage;
TLandCodepage = record
wLanguage,
wCodePage: word;
end;
var
dummy,
len: cardinal;
buf, pntr: pointer;
lang: string;
begin
len := GetFileVersionInfoSize(PChar(FileName), dummy);
if len = 0 then
GetMem(buf, len);
if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then
try
if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then
except
on EAccessViolation do begin
ShowMessage('2');
end;end;
try
lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]);
except
on EAccessViolation do begin
ShowMessage('2');
end;end;
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then
result.CompanyName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductName'), pntr, len){ and (@len <> nil)} then
result.ProductName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductVersion'), pntr, len){ and (@len <> nil)} then
result.ProductVersion := PChar(pntr);
FreeMem(buf);
end;

loo30fer
پنج شنبه 22 اردیبهشت 1390, 23:01 عصر
همچنان منتظر جواب هستم.........:ناراحت: