Как получить номер версии текущего проекта, используя ToolsAPI в Delphi 10.2
В 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 "версию" и "выпуск", но ничего подозрительного не обнаружилось.
Любые советы о том, как я могу получить информацию о версии в Delphi 10.2?
2 ответа
Действующие значения для информации о версии хранятся в отдельных конфигурациях для конфигурации сборки и платформы. Чтобы получить доступ к конфигурациям, сначала получите интерфейс к 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 CurrentPlatform и CurrentConfiguration.
Чтобы ответить на мой собственный вопрос после прочтения очень полезного ответа Уве Раабе:
Простейший код для получения информации о версии текущей активной конфигурации и платформы:
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;
Так что это довольно просто, если вам нужны только значения из текущей конфигурации (что в моем случае - именно то, что мне нужно).
- Получить текущий проект
- Получите интерфейс IOTAProjectOptionsConfigurations
- Получить текущую активную конфигурацию
- Прочитайте значения, используя GetValue. Обратите внимание на новые имена для свойств информации о версии. Также обратите внимание, что вы должны передать True для параметра IncludeInheritedValues.
Некоторые заметки:
- Вы можете перечислить доступные свойства с помощью GetPropertyCount() и GetPropertyName().
- Вместо вызова GetValue('name', True), как указано выше, вы также можете использовать свойство Value['name']. Он автоматически извлекает результирующее значение, возвращающееся в конфигурации предков по мере необходимости.
- Существует также возможность получить приведенные значения типа через свойство AsInteger. Опять же, это также принимает во внимание конфигурации предков. Обратите внимание, что это может вызвать исключения в случае сбоя преобразования типа.
- Если опция "Включить информацию о версии" не проверена для текущей конфигурации или какого-либо из предков, вызовы GetValue возвращают версию 1.0.0.0 по любой причине. Кажется, нет никакой возможности проверить этот вариант, но я могу ошибаться здесь.
- Embarcadero мог бы легко обеспечить обратную совместимость, перенаправив ProjectOptions.Values ['MajorVersion'] и связав вызовы со значениями текущей конфигурации. Конечно, они не сделали своего выбора, но в этом случае я бы ожидал некоторую документацию.
- Изменение восходит к Delphi XE.