如何使用Delphi 10.2的ToolsAPI获取当前项目的版本号

6

在Delphi 2007中,我可以使用以下ToolsAPI调用轻松获取当前项目的版本信息:

procedure Test;
var
  ProjectOptions: IOTAProjectOptions;
  Project: IOTAProject;
  Major: Variant;
  Minor: Variant;
  Release: Variant;
  Build: Variant;
begin
  // GxOtaGetCurrentProject is a function in GExpert's GX_OTAUtils unit that returns the current IOTAProject
  Project := GxOtaGetCurrentProject;
  if Assigned(Project) then begin
    ProjectOptions := Project.ProjectOptions;
    if Assigned(ProjectOptions) then begin
      Major := ProjectOptions.Values['MajorVersion'];
      Minor := ProjectOptions.Values['MinorVersion'];
      Release := ProjectOptions.Values['Release'];
      Build := ProjectOptions.Values['Build'];
    end;
  end;
end;

在Delphi 10.2.3中,无论实际版本号如何,这将始终返回版本1.0.0.0。这是"简单"的情况:一个VCL应用程序。
我还尝试了"Keys"值,它返回TStrings指针。在那里,我也得到了FileVersion字符串,但它始终是"1.0.0.0"。
我猜这与支持各种平台和配置有关,但我找不到任何文档,说明现在应该如何工作。我还搜索了ToolsAPI.pas中的"version"和"release",但没有发现任何可疑的内容。
有什么提示可以告诉我如何在Delphi 10.2中获取版本信息吗?

DDevExtensions似乎可以正常读取它。问问Andreas Hausladen? - Dave Nottage
2个回答

9

版本信息的有效值存储在不同的构建配置平台的配置中。要访问这些配置,首先需要获取到IOTAProjectOptionsConfigurations接口:

cfgOpt := project.ProjectOptions as IOTAProjectOptionsConfigurations;

然后对每个IOTABuildConfiguration进行迭代:

  for I := 0 to cfgOpt.ConfigurationCount - 1 do
  begin
    cfg := cfgOpt.Configurations[I];
    DoWhatEverWith(cfg);
  end;

请注意,每个IOTABuildConfiguration都可以有多个平台和子级:

  for S in cfg.Platforms do
  begin
    DoWhatEverWith(cfg.PlatformConfiguration[S]);
  end;

  for I := 0 to cfg.ChildCount - 1 do
  begin
    DoWhatEverWith(cfg.Children[I]);
  end;

根据当前选择的平台和构建配置,可能会使用不同的版本信息值。可以从 IOTAProject 属性 CurrentPlatformCurrentConfiguration 中检索当前平台和配置。


3

在阅读了Uwe Raabe非常有帮助的回答后,我想回答自己的问题:

获取当前活动配置和平台版本信息的最简代码如下:

procedure Test;
var
  ProjectOptions: IOTAProjectOptionsConfigurations;
  Project: IOTAProject;
  Major: Variant;
  Minor: Variant;
  Release: Variant;
  Build: Variant;
  cfg: IOTABuildConfiguration;
begin
  // GxOtaGetCurrentProject is a function in GExpert's GX_OTAUtils unit that returns the current IOTAProject
  Project := GxOtaGetCurrentProject;
  if Assigned(Project) then begin
    // as per Uwe's answer
    ProjectOptions := Project.ProjectOptions as IOTAProjectOptionsConfigurations;
    if Assigned(ProjectOptions) then begin
      // this is the currently active configuration
      cfg := ProjectOptions.ActiveConfiguration;
      if Assigned(cfg) then begin
        // Note that the names of the version properties are different!
        Major := cfg.GetValue('VerInfo_MajorVer', True);
        Minor := cfg.GetValue('VerInfo_MinorVer', True);
        Release := cfg.GetValue('VerInfo_Release', True);
        Build := cfg.GetValue('VerInfo_Build', True);
      end;
    end;
  end;
end;

只要您只需要从当前配置中获取值(这恰好是我需要的情况),那么这很容易。

  1. 获取当前项目。
  2. 获取 IOTAProjectOptionsConfigurations 接口。
  3. 获取当前活动配置。
  4. 使用 GetValue 读取值。请注意版本信息属性的新名称。另请注意,必须为 IncludeInheritedValues 参数传递 True。

一些说明:

  • 您可以使用 GetPropertyCount() 和 GetPropertyName() 枚举可用属性。
  • 除了像上面调用 GetValue('name', True) 之外,您还可以使用 Value['name'] 属性。它会自动递归到祖先配置中检索结果值。
  • 还有一个选项可以通过 AsInteger 属性获得类型转换后的值。同样,这也考虑了祖先配置。请注意,如果类型转换失败,则可能会引发异常。
  • 如果未选中“包括版本信息”选项以及当前配置或任何祖先中的任何选项,则 GetValue 调用返回版本 1.0.0.0,出于某种原因。似乎没有办法检查该选项,但我可能是错的。
  • Embarcadero 可以通过将 ProjectOptions.Values['MajorVersion'] 和相关调用重定向到当前配置的值来轻松提供向后兼容性。他们没有这样做,这是他们的选择,但在这种情况下,我希望有一些文档。
  • 更改追溯到 Delphi XE。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接