【问题标题】:How to get a list of all packages required by another package如何获取另一个包所需的所有包的列表
【发布时间】:2018-01-10 05:26:19
【问题描述】:

我的应用程序使用运行时包,我想获得其中之一所需的所有包的列表。

示例:

PackA.bpl 需要 PackB.bpl 和 PackC.bpl。

如何在运行时从 PackA.bpl 获取所需的包? (在本例中,它们是 PackB.bpl 和 PackC.bpl)

【问题讨论】:

  • 你为什么会遇到这种情况。在编写包时,您会知道这些信息。你忘了,还是包裹是从别处来的?如果是后者,则应记录其依赖关系。那么动态加载的包呢?
  • @DavidHeffernan:你好! PackA.bpl 是一个动态加载的包,用于下载应用程序使用的所有包的更新。运行后,PackA 被卸载,下载的包文件被替换。如果已下载另一个 PackA.bpl,则有一个备份系统将最后一个工作的 PackA.bpl 保存在备份文件夹中。目前,PackA 正在导入所有内容。
  • 另一种解决方案是将 PackA 所需的所有包保存在备份文件夹中,但在这种情况下,我宁愿不要“手动”设置它们,因为它们可以更改,我会更愿意减少做错事的可能性。
  • 就像我说的,您在编写包并列出其依赖项时就知道这些信息。
  • 仅备份更改的文件。 (如果需要,您可以备份更多,但为什么要将客户的空间浪费在重复文件上?)如果您发现 PackA 不起作用,则从该备份中恢复所有内容。该政策不会出错。具体来说,如果 PackC 发生更改,则将其包含在备份中。将每个备份集分开:更新 1 创建备份 1,更新 2 创建备份 2。不要将备份 1 和备份 2 中的文件混在一起,否则在恢复时,您将不知道哪些文件是兼容的。跨度>

标签: delphi dependencies packages delphi-2007


【解决方案1】:

您可以从SysUtils 使用GetPackageInfoHere 是一个使用它来枚举在包中编译的单元列表的示例(在您的情况下,在您的回调中检查 ntRequiresPackage 代替)。例如:

procedure GetRequiredPackageName(const Name: string; NameType: TNameType; Flags: Byte; Param: Pointer);
var
  Names: TStrings absolute Param;
begin
  case NameType of
    ntRequiresPackage:
      Names.Add(Name);
  end;
end;

procedure GetRequiredPackageNames(Module: HMODULE; Names: TStrings);
var
  Flags: Integer;
begin
  Names.BeginUpdate;
  try
    GetPackageInfo(Module, Names, Flags, GetRequiredPackageName);
  finally
    Names.EndUpdate;
  end;
end;

function ListRequiredPackages(HInstance: NativeInt; Data: Pointer): Boolean;
var
  Names: TStrings absolute Data;
  I: Integer;
begin
  Result := True;
  Names.Clear;
  GetRequiredPackageNames(HInstance, Data);
  Writeln(Format('%s requires: %d packages', [ExtractFileName(GetModuleName(HInstance)), Names.Count]));
  if Names.Count > 0 then
    for I := 0 to Names.Count - 1 do
      Writeln(Names[I]);
end;

procedure Main;
var
  Names: TStringList;
  I: Integer;
begin
  Names := TStringList.Create;
  try
    EnumModules(ListRequiredPackages, Names);
    Readln;
  finally
    Names.Free;
  end;
end;

要通过名称获取包的句柄,可以使用GetModuleHandle

ListRequiredPackages(GetModuleHandle('PackA.bpl'), Names);

【讨论】:

  • @Hwau 调用 GetPackageInfo,并在您的回调中检查 ntRequiresPackage
  • 是的,如果可执行文件是 bpl,您可以加载它并使用其句柄调用 GetPackageInfo。如果它是一个 exe,你可以枚举它的导入。
  • 是的,我已经说过了。此外,这与您最初提出的问题完全不同。
猜你喜欢
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 2012-01-29
  • 2021-01-03
  • 1970-01-01
  • 2018-10-23
  • 2013-03-31
相关资源
最近更新 更多