delphi – 如何获取正在运行的可执行文件的版本?
我怎样才能获得正在运行的应用程序的版本?
我一直在使用 filename := PChar(ExtractShortPathName(ParamStr(0))); //Get the number of bytes he have to allocate for the file information structure dwInfoLength := GetFileVersionInfoSize(lptstrFilename,{var}dwHandle); //Get version info GetMem(pInfoData,dwInfoLength); GetFileVersionInfo(lptstrFilename,dwHandle,dwInfoLength,pInfoData); //Set what information we want to extract from pInfoData lpSubBlock := PChar(Chr(92)+Chr(0)); //Extract the desired data from pInfoData into the FileInformation structure VerQueryValue(pInfoData,lpSubBlock,PFileInformation,LengthOfReturned); 这种技术的问题是它需要Windows加载器到load the image before the resources can be read.我使用 这会导致Windows加载程序再次通过网络加载整个图像,而不是仅仅查看“我”.由于我在启动时检查并保存了我自己的版本,因此6秒的应用程序启动变成了10秒的应用程序启动. 我如何阅读我的版本,我正在运行的应用程序? 我会假设Windows没有API来读取正在运行的进程的版本,只有我加载的文件(如果文件不再存在,那么它无法读取任何版本信息). 但我也假设有可能从我的进程自己的内存中读取版本资源(当然不是Administrators或Debuggers组的成员). 我可以阅读我的流程版本吗? 相关奖金问题:如何从我而不是通过网络加载PE图像资源? 解决方法
在Stackoverflow上找到它:
How to determine Delphi Application Version 我已经知道如何确定一个应用程序版本,但@StijnSanders提出了“更好”的方式,正是因为我正在打击的原因:
我改编成: 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; ...
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |