7

静的コード分析ツールの場合、プロジェクトレベルおよびグローバルIDE構成で定義されている、特定のDelphiプロジェクトのすべての有効なソースパスを知る必要があります。

この種のプロジェクト情報を収集できるDelphiライブラリはありますか?

私の知る限り、Delphi IDEのレジストリ設定は、複数の構成をサポートするために、さまざまな場所に配置できます。ただし、IDEレジストリの場所とプロジェクトファイルの特定の組み合わせについては、ソースパスを収集できる必要があります。

編集:別の解決策は、-dependsスイッチを使用することです。これにより、dcc32.exeは、パス名を含むプロジェクトのすべてのdcuファイル名(およびすべての依存関係)を含む「.d」ファイルを書き込みます。ただし、ファイルリストにはすでにコンパイルされているユニットが含まれているため、元の問題の正しい解決策ではありません。

4

2 に答える 2

12

OpenTools APIを使用して、アクティブなプロジェクトの検索パス(アクティブな構成とオプションセットからマージされたもの)とIDEのグローバルライブラリパスを取得できます。これが私のクイックテストデザインパッケージのユニットです。

unit Unit1;

interface

uses
  Windows, SysUtils, Classes,
  ToolsAPI;

type
  TTestWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
  private
    { IOTAWizard }
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    procedure Execute;
    { IOTAMenuWizard }
    function GetMenuText: string;
  private
    function AddLibraryPaths(Strings: TStrings): Integer;
    function AddProjectSearchPaths(Strings: TStrings): Integer;
  end;

procedure Register;

implementation

uses
  Dialogs,
  DCCStrs, TypInfo;

var
  WizardIndex: Integer = -1;

procedure GetEnvironmentVariables(Strings: TStrings);
var
  P: PChar;
begin
  P := nil;
  Strings.BeginUpdate;
  try
    Strings.Clear;
    P := GetEnvironmentStrings;
    repeat
      Strings.Add(P);
      P := StrEnd(P);
      Inc(P);
    until P^ = #0;
  finally
    if Assigned(P) then
      FreeEnvironmentStrings(P);
    Strings.EndUpdate;
  end;
end;

function EvaluateEnvironmentVariables(const S: string): string;
var
  Strings: TStringList;
  I: Integer;
begin
  Result := S;

  Strings := TStringList.Create;
  try
    GetEnvironmentVariables(Strings);
    for I := 0 to Strings.Count - 1 do
      Result := StringReplace(Result, Format('$(%s)', [Strings.Names[I]]), Strings.ValueFromIndex[I],
        [rfReplaceAll, rfIgnoreCase]);
  finally
    Strings.Free;
  end;
end;

procedure Register;
begin
  WizardIndex := (BorlandIDEServices as IOTAWizardServices).AddWizard(TTestWizard.Create);
end;

{ TTestWizard private: IOTAWizard }

function TTestWizard.GetIDString: string;
begin
  Result := 'TOndrej.TestWizard';
end;

function TTestWizard.GetName: string;
begin
  Result := 'TestWizard';
end;

function TTestWizard.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

procedure TTestWizard.Execute;
var
  Paths: TStrings;
begin
  Paths := TStringList.Create;
  try
    AddProjectSearchPaths(Paths);
    AddLibraryPaths(Paths);
    ShowMessage(EvaluateEnvironmentVariables(Paths.Text));
  finally
    Paths.Free;
  end;
end;

{ TTestWizard private: IOTAMenuWizard }

function TTestWizard.GetMenuText: string;
begin
  Result := GetIDString;
end;

function TTestWizard.AddLibraryPaths(Strings: TStrings): Integer;
var
  Paths: TStringList;
  EnvironmentOptions: IOTAEnvironmentOptions;
begin
  Paths := TStringList.Create;
  try
    Paths.Delimiter := ';';
    Paths.StrictDelimiter := True;
    EnvironmentOptions := (BorlandIDEServices as IOTAServices).GetEnvironmentOptions;
    Paths.DelimitedText := EnvironmentOptions.Values['LibraryPath'];
    Strings.AddStrings(Paths);
    Result := Paths.Count;
  finally
    Paths.Free;
  end;
end;

function TTestWizard.AddProjectSearchPaths(Strings: TStrings): Integer;
var
  ActiveProject: IOTAProject;
  Configurations: IOTAProjectOptionsConfigurations;
  Configuration: IOTABuildConfiguration;
  Paths: TStringList;
begin
  Result := -1;
  ActiveProject := GetActiveProject;
  if not Assigned(ActiveProject) then
    Exit;
  Configurations := ActiveProject.ProjectOptions as IOTAProjectOptionsConfigurations;
  Configuration := Configurations.ActiveConfiguration;
  if not Assigned(Configuration) then
    Exit;

  Paths := TStringList.Create;
  try
    Configuration.GetValues(sUnitSearchPath, Paths, True);
    Strings.AddStrings(Paths);
    Result := Paths.Count;
  finally
    Paths.Free;
  end;
end;

initialization

finalization
  if WizardIndex <> -1 then
    (BorlandIDEServices as IOTAWizardServices).RemoveWizard(WizardIndex);

end.
于 2009-06-09T20:58:07.053 に答える
11

別の解決策を見つけました:

RADStudioコマンドプロンプトを起動して実行した場合

msbuild /t:Rebuild

プロジェクトディレクトリで、msbuildは、すべてのパス設定を含む、dcc32を呼び出すための完全なコマンドラインを表示します。ビルドログをファイルにリダイレクトし(またはdcc32.exeをパラメーターのみをキャプチャする自作バージョンに置き換える)、出力を解析する方が、dprojファイルを解析するよりもはるかに簡単なようです。

もう1つの利点は、自動ビルド/継続的インテグレーションで使用できることです。

于 2009-06-11T06:15:15.550 に答える