Delphi 可执行版本总是返回相同的值

Soo*_*tos 0 delphi

我正在尝试获取正在运行的可执行文件的版本,以便我知道我的应用程序何时更改为具有新功能的新版本。

我正在使用以下代码来获取版本:

function GetVersaoExe: string;
type
   PFFI = ^vs_FixedFileInfo;
var
   F : PFFI;
   Handle : Dword;
   Len : Longint;
   Data : Pchar;
   Buffer : Pointer;
   Tamanho : Dword;
   Parquivo: Pchar;
   Arquivo : string;
begin
   Arquivo := Application.ExeName;
   Parquivo := StrAlloc(Length(Arquivo) + 1);
   StrPcopy(Parquivo, Arquivo);
   Len := GetFileVersionInfoSize(Parquivo, Handle);
   ShowMessage(IntToStr(Len));
   Result := '';
   if Len > 0 then
   begin
      Data:=StrAlloc(Len+1);
      if GetFileVersionInfo(Parquivo,Handle,Len,Data) then
      begin
         VerQueryValue(Data, '\',Buffer,Tamanho);
         F := PFFI(Buffer);
         Result := Format('%d.%d.%d.%d',
         [HiWord(F^.dwFileVersionMs),
         LoWord(F^.dwFileVersionMs),
         HiWord(F^.dwFileVersionLs),
         Loword(F^.dwFileVersionLs)]
         );
      end;
      StrDispose(Data);
   end;
   StrDispose(Parquivo);
end;
Run Code Online (Sandbox Code Playgroud)

这将返回数字4.0.1.1

问题是我已经使用这个函数有一段时间了,它从来没有改变过这个数字,它总是4.0.1.1,我需要一个每次重建应用程序时都会改变的数字,以了解自上次以来发生了一些变化建造。

我检查了其他三种获取版本号的方法,它们碰巧都在做同样的事情。

StackOverFlow 上有一个类似的问题,但我仍然不知道它是否有效。我检查了这个问题并尝试使用他们的方式,但还有另一个问题。当我ToolsAPI在我的使用单位中导入使用IOTAProjectOptionsConfigurations并给我以下错误:Cannot compile unit ToolsAPI.

最后我试图解决最后一个问题,但我不能。

Rem*_*eau 5

只需将您的项目配置为在每个新构建中自动增加版本号。项目选项中的版本信息页面有一个用于此目的的复选框。


也就是说,在您展示的代码中,您根本不需要使用StrAlloc()/ StrDispose()。只需将PChar(Arquivo)作为输入传递给GetFileVersionInfoSize()and GetFileVersionInfo(),并更改Data为 an array of Byte(或者TBytes如果您的 Delphi 版本有它) usingSetLength()来分配它并让编译器自动释放它。

function GetVersao(const Arquivo: String): string;
type
  PFFI = ^vs_FixedFileInfo;
var
  F : PFFI;
  Handle : Dword;
  Len : Longint;
  Data : array of Byte; // or TBytes
  Buffer : Pointer;
  Tamanho : Dword;
begin
  Result := '';
  Len := GetFileVersionInfoSize(PChar(Arquivo), Handle);
  ShowMessage(IntToStr(Len));
  if Len > 0 then
  begin
    SetLength(Data, Len);
    if GetFileVersionInfo(PChar(Arquivo), Handle, Len, PByte(Data)) then
    begin
      if VerQueryValue(PByte(Data), '\', Buffer, Tamanho) then
      begin
        F := PFFI(Buffer);
        Result := Format('%d.%d.%d.%d',
          [HiWord(F^.dwFileVersionMs),
          LoWord(F^.dwFileVersionMs),
          HiWord(F^.dwFileVersionLs),
          Loword(F^.dwFileVersionLs)]
        );
      end;
    end;
  end;
end;

function GetVersaoExe: string;
begin
  Result := GetVersao(Application.ExeName);
end;
Run Code Online (Sandbox Code Playgroud)

如果你真的想变得圆滑,你甚至根本不需要使用GetFileVersionInfo/Size()。您可以使用(Find|Load|Lock)Resource()直接访问调用进程的RT_VERSION资源:

function GetVersao(Module: THandle): string;
type
  PFFI = ^vs_FixedFileInfo;
var
  F : PFFI;
  Len : Longint;
  Data : array of Byte; // or TBytes
  Buffer : Pointer;
  Tamanho : Dword;
  hRes, hResData: THandle;
begin
  Result := '';
  hRes := FindResource(Module, MAKEINTRESOURCE(1), RT_VERSION);
  Len := SizeOfResource(hRes);
  ShowMessage(IntToStr(Len));
  if Len > 0 then
  begin
    hResData := LoadResource(Module, hRes);
    Buffer := LockResource(hResData);
    SetLength(Data, Len);
    Move(Buffer^, Data[0], Len);
    if VerQueryValue(PByte(Data), '\', Buffer, Tamanho) then
    begin
      F := PFFI(Buffer);
      Result := Format('%d.%d.%d.%d',
        [HiWord(F^.dwFileVersionMs),
        LoWord(F^.dwFileVersionMs),
        HiWord(F^.dwFileVersionLs),
        Loword(F^.dwFileVersionLs)]
      );
    end;
  end;
end;

function GetVersaoExe: string;
begin
  Result := GetVersao(GetModuleHandle(nil));
end;
Run Code Online (Sandbox Code Playgroud)