我一直在使用GetFileVersionInfo(ParamStr(0),...)
:
filename := PChar(ExtractShortPathname(ParamStr(0)));//Get the number of bytes he have to allocate for the file information structureDWInfolength := GetFiLeversionInfoSize(lptstrfilename,{var}DWHandle);//Get version infoGetMem(pInfoData,DWInfolength);GetFiLeversionInfo(lptstrfilename,DWHandle,DWInfolength,pInfoData);//Set what information we want to extract from pInfoDatalpSubBlock := PChar(Chr(92)+Chr(0));//Extract the desired data from pInfoData into the fileinformation structureVerqueryValue(pInfoData,lpSubBlock,Pfileinformation,LengthOfReturned);
这种技术的问题是它需要windows加载器到load the image before the resources can be read.我使用IMAGE_FILE_NET_RUN_FROM_SWAP
图像标志(in order to avoid in-page exceptions on a fiddly network)构建我的应用程序.
这会导致windows加载程序再次通过网络加载整个图像,而不是仅仅查看“我”.由于我在启动时检查并保存了我自己的版本,因此6秒的应用程序启动变成了10秒的应用程序启动.
我如何阅读我的版本,我正在运行的应用程序?
我会假设windows没有API来读取正在运行的进程的版本,只有我加载的文件(如果文件不再存在,那么它无法读取任何版本信息).
但我也假设有可能从我的进程自己的内存中读取版本资源(当然不是administrators或DeBUGgers组的成员).
我可以阅读我的流程版本吗?
相关奖金问题:如何从我而不是通过网络加载PE图像资源?
解决方法 在Stackoverflow上找到它:How to determine Delphi Application Version
我已经知道如何确定一个应用程序版本,但@StijnSanders提出了“更好”的方式,正是因为我正在打击的原因:
I most strongly recommend not to use GetFiLeversion when you want to kNow the version of the executable that is currently running! I have two pretty good reasons to do this:
The executable may be unaccessible (disconnected drive/share),or changed (.exe renamed to .bak and replaced by a new .exe without the running process being stopped). The version data you’re trying to read has actually already been loaded into memory,and is available to you by loading this resource,which is always better than to perform extra (relatively slow) disk operations.
我改编成:
function GetModuLeversion(Instance: THandle; out iMajor,iMinor,iRelease,iBuild: Integer): Boolean;var fileinformation: PVSFIXEDfileINFO; verlen: Cardinal; rs: TResourceStream; m: TMemoryStream; resource: HRSRC;begin //You saID zero,but you mean "us" if Instance = 0 then Instance := HInstance; //UPDATE: Workaround BUG in Delphi if resource doesn't exist resource := FindResource(Instance,1,RT_VERSION); if (resource = 0) begin iMajor := 0; iMinor := 0; iRelease := 0; iBuild := 0; Result := False; Exit; end; m := TMemoryStream.Create; try rs := TResourceStream.CreateFromID(Instance,RT_VERSION); try m.copyFrom(rs,rs.Size); finally rs.Free; end; m.position:=0; if not VerqueryValue(m.Memory,'\',/*var*/Pointer(fileinformation),/*var*/verlen) then begin iMajor := 0; iMinor := 0; iRelease := 0; iBuild := 0; Exit; end; iMajor := fileinformation.DWFiLeversionMS shr 16; iMinor := fileinformation.DWFiLeversionMS and $FFFF; iRelease := fileinformation.DWFiLeversionLS shr 16; iBuild := fileinformation.DWFiLeversionLS and $FFFF; finally m.Free; end; Result := True;end;
警告:由于Delphi中的错误,上面的代码有时会崩溃:
rs := TResourceStream.CreateFromID(Instance,RT_VERSION);
如果没有版本信息,Delphi会尝试引发异常:
procedure TResourceStream.Initialize(Instance: THandle; name,ResType: PChar); procedure Error; begin raise EResNotFound.CreateFmt(SResNotFound,[name]); end;begin HResInfo := FindResource(Instance,name,ResType); if HResInfo = 0 then Error; ...end;
当然,错误是PChar并不总是指向ansi char的指针.对于非命名资源,它们是整数常量,强制转换为PChar.在这种情况下:
name: PChar = PChar(1);
当Delphi尝试构建异常字符串,并取消引用指针0x00000001时,它会触发并访问违规.
修复是首先手动调用FindResource(Instance,RT_VERSION):
var ... resource: HRSRC;begin ... resource := FindResource(Instance,RT_VERSION); if (resource = 0) begin iMajor := 0; iMinor := 0; iRelease := 0; iBuild := 0; Result := False; Exit; end; m := TMemoryStream.Create; ...
总结Note: Any code is released into the public domain. No attribution required.
以上是内存溢出为你收集整理的delphi – 如何获取正在运行的可执行文件的版本?全部内容,希望文章能够帮你解决delphi – 如何获取正在运行的可执行文件的版本?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)