2015-05-12 26 views
1

我的应用程序使用了运行时软件包,我想获取其中一个软件包所需的所有软件包的列表。如何获取另一个软件包所需的所有软件包的列表

实施例:

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

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

+0

为什么你发现自己在这种情况下。编写软件包时,你知道这些信息。你忘了,还是来自其他地方?如果后者的依赖性应该记录在案。那么动态加载的包呢? –

+0

@DavidHeffernan:你好! PackA.bpl是一个动态加载的软件包,用于下载应用程序使用的所有软件包的更新。运行后,PackA被UnLoaded并且下载的包文件被替换。如果下载了另一个PackA.bpl,则会有一个备份系统将上次工作的PackA.bpl保存在备份文件夹中。目前,PackA正在导入一切。 – ExDev

+0

另一个解决方案是将PackA所需的所有包保存到备份文件夹中,但在这种情况下,我宁愿不将它们设置为“手动”,因为它们可以更改,我宁愿减少做某件事的可能性错误。 – ExDev

回答

3

您可以使用SysUtilsGetPackageInfoHere是一个使用它枚举包中编译的单元列表的示例(在您的情况下,在您的回调检查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); 
+0

我读了链接的问题,但我仍不明白如何获取所有必需软件包的列表。 – Hwau

+1

@Hwau调用GetPackageInfo,并在您的回调检查中找到'ntRequiresPackage'。 –

+0

你是对的,谢谢。用示例代码编辑的问题消息。如何用可执行文件做同样的事情? – Hwau

相关问题