【问题标题】:Programmatically get all units used in a dpr in Delphi以编程方式获取 Delphi 中 dpr 中使用的所有单位
【发布时间】:2014-10-09 19:57:56
【问题描述】:

我是 Delphi 的新手,我正在尝试制作一个应用程序,我将在其中提供一个 .dpr 文件作为输入,该应用程序将创建一个列表,其中包含此 .dpr 使用的所有 .pas 文件......我仍然无法在 Delphi 中找到函数或读取 .dpr 用途的方法,以便通过文件系统导航到这些 pas 文件并读取它们的用途,等等......有没有人知道如何实现这个?

【问题讨论】:

  • Delphi 没有内置功能来做到这一点。要么写一个解析器,要么找一个第三方的。为什么你还需要这样做?
  • 你可以使用一个工具,DUDS, Delphi Unit Dependency Scanner
  • 另外:从 exe,而不是 dpr,您可以从以下资源之一获取单元列表:RCData / PACKAGEINFO。不是答案,但也许是另一种选择。
  • 非常感谢你们!我会更好地了解每个解决方案......大卫,我想创建一个应用程序,我将在其中提供一个 .dpr,它将复制到文件系统中的另一个文件夹,所有与此 .dpr 相关的单位。这样,即使我在其他项目使用的同一文件夹中有 .pas 文件,我也可以轻松获得项目所有必要单元的副本。
  • 您的版本控制系统是您需要使用的。请告诉我您正在使用修订控制。

标签: delphi delphi-xe4


【解决方案1】:

这并不简单:您不仅需要读取.dpr 文件,还需要解析.dproj 和注册表以获取搜索路径。如果您尝试正确执行此操作,您还必须将 .dpr.pas 文件解析为代码文件,以便您可以找到使用语句、处理 {$I '...'} 包含、{$IFDEF} 块、interfaceimplementation 部分,等等。

综上所述,您可能希望从开源 CnPack 和 GExperts 项目中寻找灵感。他们俩都解决了这个问题,您可以利用他们的工作来解决您要解决的任何问题。

【讨论】:

    【解决方案2】:

    如果您让 Delphi 创建一个 .map 文件(链接器选项),它将包含该项目中使用的所有源文件和 dcu 文件的列表。 GExperts 使用一个简单的解析器来处理从我的 dzlib https://sourceforge.net/p/dzlib/code/HEAD/tree/dzlib/trunk/src/u_dzMapFileReader.pas 获取的地图文件。

    【讨论】:

      【解决方案3】:

      我想更新这个问题以获得可能的答案以供将来参考。

      创建一个单独的单元文件(PhonyObject.pas)

      unit PhonyObject;
      
      interface
      
      uses
        System.Classes, FMX.Forms, FMX.Dialogs;
      
      type
        TPhonyObject = class(TObject)
        end;
      
        TPhonyClass = class of TPhonyObject;
      
      procedure FindUnitName(anObject: TObject);
      
      var
        PhonyName: string;
        PhonyClass: TPhonyClass;
        PhonyInstance: TObject;
        PhonyClassName: procedure(anObject: TObject) = FindUnitName;  //function: String = FindUnitName;
      
      implementation
      
      uses System.TypInfo;
      
      procedure FindUnitName(anObject: TObject);
      begin
        if anObject <> nil then  PhonyName := anObject.UnitName
        else if not (TObject.UnitName <> 'System') then
        begin
          if TypInfo.GetTypeData(anObject.ClassInfo) <> nil then  PhonyName := String(GetTypeData(anObject.ClassInfo)^.UnitName);
        end else  PhonyName := TObject.UnitName;
        //FreeAndNilProperties
      end;
      
      initialization
        PhonyClass := TPhonyObject;
        PhonyInstance := PhonyClass.Create;
      
        ShowMessage('Unit Name =' + PhonyInstance.UnitName);
      
        PhonyInstance.Free;
      
      
      finalization
        PhonyClass := nil; //PhonyClass.Free;
      
      end.
      

      为了在另一个(多个)单元中使用它,这是我迄今为止使用的代码,但我希望稍后更新它。我在一个手工制作的“控制台”中显示了这个,它在 TMemo 中具有黑色背景和白色文本。如果有人想要 TMemo 的代码(它并不为人所知),或者如何在基本上调试窗口中显示所有这些,您只需告诉我。这是迄今为止我得到的最好的,但我需要更好地了解子/父对象/类

      unit AnotherUnit;
      
      interface
      
      uses
        System.Classes, PhonyObject;
      
      type
        TPhonyObj = class(TPhonyObject)
        end;
      
      //var
      
      implementation
      
      {$R *.fmx}
      
      uses ...;
      
      initialization
      
        PhonyClass := TPhonyObj;
        PhonyInstance := PhonyClass.Create;
      
        ShowMessage('UnitName= ' + PhonyInstance.UnitName + ' (AnotherUnit)'); // PhonyClass.UnitName  // PhonyClassName(PhonyInstance);
      
        PhonyInstance.Free;
      
      finalization
        PhonyClass := nil;
      
      end;
      

      我尽可能地使用了单元名称和类名称的唯一性,并且我意识到直到最后我实际上并没有使用任何对象,但它应该没有任何问题。如果有更好的想法,请发表评论,但我认为这是 Delphi 编程的一个强大功能,因为您可以预测某些单元名称何时会突然出现。以及如何预测它们。

      【讨论】:

      • 这样看,初始化发生了。必要的代码在这里通知应用程序哪个单元初始化首先发生,这样附加代码只需要处理条件语句以确保先前的单元已经预先执行。例如,如果您需要在 1 个单元中创建一个数据库,连接到它,这样下一个单元可以确定它已经完成,然后继续。当然,有一些语句可以首先检查表或数据库是否存在。这样如果需要附加
      • 您也可以在初始化中创建对象。您所要做的就是添加额外的库。因此可以完成申请的整个过程的一部分。只需在初始化中。
      • 巴里,你为什么要那样做?在我看来,单元初始化是为了设置无法以其他方式初始化的核心数据结构。您在这里展示的内容非常类似于 Factory Design Pattern 以及延迟初始化。恕我直言,纯粹在单元初始化中初始化复杂的应用程序对象结构相当笨拙——它与单例相关联,您如何通知用户并提供“重试”按钮?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      相关资源
      最近更新 更多