2009-06-09 16 views
6

Per gli strumenti di analisi del codice statico, è necessario conoscere tutti i percorsi sorgente effettivi per un determinato progetto Delphi, definiti a livello di progetto e nella configurazione IDE globale.Esiste una libreria Delphi che restituisce tutti i percorsi di origine efficaci per un progetto?

Esiste una libreria Delphi in grado di raccogliere questo tipo di informazioni sul progetto?

Per quanto ne so, le impostazioni del Registro di sistema per l'IDE Delphi possono trovarsi in posizioni diverse, per supportare più configurazioni. Ma per una data combinazione della posizione del registro IDE e di un file di progetto, dovrebbe essere possibile raccogliere i percorsi di origine.

Modifica: Un'altra soluzione è utilizzare l'opzione --depends. Ciò farà sì che dcc32.exe scriva un file ".d" con tutti i nomi di file dcu del progetto (e tutte le dipendenze), compresi i nomi dei percorsi. Tuttavia, l'elenco dei file include unità già compilate, quindi non è una soluzione corretta per il problema originale.

+0

Qualsiasi versione Delphi specifica per cui vuoi sapere questo? –

+0

Delphi 2009 - perché è molto più complicato con configurazioni di build che possono anche essere ereditate e possono contenere macro come $ (DCC_UnitSearchPath) - questo sembra essere più difficile del previsto ... – mjn

risposta

8

Appena trovato un'altra soluzione:

se lancio il prompt dei comandi RAD Studio e corro

msbuild /t:Rebuild 

nella directory del progetto, msbuild mostrerà la riga di comando completa per richiamare dcc32, incluse tutte le impostazioni del percorso. Il reindirizzamento del log di build in un file (o la sostituzione di dcc32.exe con una versione autoprocessata che cattura solo i parametri) e l'analisi dell'output sembra essere molto più semplice che analizzare i file dproj.

Un altro vantaggio è che può essere utilizzato in build automatizzati/integrazione continua.

10

È possibile utilizzare OpenTools API per ottenere il percorso di ricerca del progetto attivo (unito dalla configurazione attiva e set di opzioni) e il percorso della libreria globale dell'IDE. Ecco un'unità dal mio rapido pacchetto di progettazione di test:

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. 
+0

Questo sembra molto promettente, grazie molto tanto! Daremo un'occhiata più da vicino all'OTA. È facile ottenere un elenco dei file di origine del progetto (tutti i file che sono stati aggiunti esplicitamente al DPR)? Daremo anche un'occhiata alle fonti di GExpert/cnWizard. – mjn

+0

Sì, con OTA è possibile enumerare i moduli di un progetto. Dai un'occhiata all'interfaccia IOTAProject. In particolare, i metodi IOTAProject40 GetModuleCount, GetModule. –

Problemi correlati