我正在尝试获取正在运行的可执行文件的版本,以便我知道我的应用程序何时更改为具有新功能的新版本。
我正在使用以下代码来获取版本:
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.
最后我试图解决最后一个问题,但我不能。
只需将您的项目配置为在每个新构建中自动增加版本号。项目选项中的版本信息页面有一个用于此目的的复选框。
也就是说,在您展示的代码中,您根本不需要使用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)