5

在 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 应用程序。

我还尝试了返回 TStrings 指针的“Keys”值。在那里我也得到了 FileVersion 字符串,但它总是“1.0.0.0”。

我想这与对各种平台和配置的支持有关,但我找不到任何关于它现在应该如何工作的文档。我还在 ToolsAPI.pas 中搜索了“版本”和“发布”,但没有出现任何可疑情况。

关于如何在 Delphi 10.2 中获取版本信息的任何提示?

4

2 回答 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中检索。

于 2018-07-04T20:53:14.703 回答
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。
于 2018-07-05T07:44:30.583 回答