是否有一个Delphi库可以返回项目的所有有效源路径?
对于静态代码分析工具,需要知道给定Delphi项目的所有有效源代码路径,这些路径在项目级别和全局IDE配置中定义 是否有可以收集此类项目信息的Delphi库 据我所知,DelphiIDE的注册表设置可以位于不同的位置,以支持多种配置。但是对于IDE注册表位置和项目文件的给定组合,应该可以收集源路径是否有一个Delphi库可以返回项目的所有有效源路径?,delphi,path,code-analysis,delphi-2009,Delphi,Path,Code Analysis,Delphi 2009,对于静态代码分析工具,需要知道给定Delphi项目的所有有效源代码路径,这些路径在项目级别和全局IDE配置中定义 是否有可以收集此类项目信息的Delphi库 据我所知,DelphiIDE的注册表设置可以位于不同的位置,以支持多种配置。但是对于IDE注册表位置和项目文件的给定组合,应该可以收集源路径 编辑:另一种解决方案是使用--depends开关。这将导致dcc32.exe写入一个“.d”文件,其中包含项目的所有dcu文件名(以及所有依赖项),包括路径名。但是,文件列表包含已编译的单元,因此它不
编辑:另一种解决方案是使用--depends开关。这将导致dcc32.exe写入一个“.d”文件,其中包含项目的所有dcu文件名(以及所有依赖项),包括路径名。但是,文件列表包含已编译的单元,因此它不是解决原始问题的正确解决方案。您可以使用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.
单元1;
接口
使用
Windows、SysUtils、类、,
图尔萨皮;
类型
TTestWizard=类(TNotifierObject、IOTAWizard、IOTAMenuWizard)
私有的
{IOTAWizard}
函数GetIDString:string;
函数GetName:string;
函数GetState:TWizardState;
程序执行;
{IOTAMenuWizard}
函数GetMenuText:string;
私有的
函数addLibraryPath(字符串:TStrings):整数;
函数addProjectSearchPath(字符串:TStrings):整数;
结束;
程序登记册;
实施
使用
对话,
DCCStrs,TypInfo;
变量
向导索引:整数=-1;
过程GetEnvironmentVariables(字符串:TStrings);
变量
P:PChar;
开始
P:=零;
Strings.BeginUpdate;
尝试
字符串。清晰;
P:=GetEnvironmentString;
重复
字符串。添加(P);
P:=强度(P);
公司(P),;
直到P^=#0;
最后
如果分配(P),则
自由环境字符串(P);
Strings.EndUpdate;
结束;
结束;
函数EvaluateEnvironmentVariables(const S:string):string;
变量
字符串:TStringList;
I:整数;
开始
结果:=S;
字符串:=TStringList.Create;
尝试
GetEnvironmentVariables(字符串);
对于I:=0到字符串。计数-1 do
结果:=StringReplace(结果,格式(“$(%s)”,[Strings.Names[I]],Strings.ValueFromIndex[I],
[rfReplaceAll,rfIgnoreCase]);
最后
字符串。免费;
结束;
结束;
程序登记册;
开始
WizardIndex:=(作为IOTAWizardServices的设备)。添加向导(TTestWizard.Create);
结束;
{TTestWizard private:IOTAWizard}
函数TTestWizard.GetIDString:string;
开始
结果:='TOndrej.TestWizard';
结束;
函数TTestWizard.GetName:string;
开始
结果:='TestWizard';
结束;
函数TTestWizard.GetState:TWizardState;
开始
结果:=[wsEnabled];
结束;
程序Twiszard.Execute;
变量
路径:TStrings;
开始
路径:=TStringList.Create;
尝试
AddProjectSearchPath(路径);
添加库路径(路径);
ShowMessage(EvaluateEnvironmentVariables(path.Text));
最后
免费的;
结束;
结束;
{TTestWizard private:IOTAMenuWizard}
函数TTestWizard.GetMenuText:string;
开始
结果:=GetIDString;
结束;
函数TTestWizard.AddLibraryPath(Strings:TStrings):整数;
变量
路径:TStringList;
环境选项:IoTaenEnvironment选项;
开始
路径:=TStringList.Create;
尝试
路径。分隔符:=';';
Paths.StrictDelimiter:=True;
EnvironmentOptions:=(将设备作为IoTaskServices)。GetEnvironmentOptions;
Paths.DelimitedText:=EnvironmentOptions.Values['LibraryPath'];
Strings.AddStrings(路径);
结果:=路径。计数;
最后
免费的;
结束;
结束;
函数TTestWizard.AddProjectSearchPath(Strings:TStrings):整数;
变量
活动项目:物联网项目;
配置:物联网项目选项配置;
配置:IOTABuildConfiguration;
路径:TStringList;
开始
结果:=-1;
ActiveProject:=GetActiveProject;
如果未分配(ActiveProject),则
出口
配置:=ActiveProject.ProjectOptions作为IOTAProjectOptions配置;
配置:=Configurations.ActiveConfiguration;
如果未分配(配置),则
出口
路径:=TStringList.Create;
尝试
getvalue(sUnitSearchPath,path,True);
Strings.AddStrings(路径);
结果:=路径。计数;
最后
免费的;
结束;
结束;
初始化
定稿
如果索引为-1,则
(将设备作为IOTAWizardServices)移除向导(WizardIndex);
结束。
刚刚找到另一个解决方案:
如果我启动RAD Studio命令提示符并运行
msbuild /t:Rebuild
在项目目录中,msbuild将显示调用dcc32的完整命令行,包括所有路径设置。将构建日志重定向到一个文件(或者用只捕获参数的自制版本替换dcc32.exe)并解析输出似乎比解析dproj文件容易得多
另一个优点是,它可以用于自动构建/持续集成。您想知道的任何特定Delphi版本?Delphi 2009-因为它的构建配置更复杂,甚至可以继承,并且可以包含诸如“$(DCC\U UnitSearchPath)之类的宏“-这似乎比预期的难…这看起来很有希望,非常感谢!我会仔细看看在线旅行社。很容易获得项目源文件的列表(所有已明确添加到DPR的文件)?我还将看看GExpert/cnWizard的源代码。是的,通过OTA,您可以枚举项目的模块。查看IOTAProject接口。具体来说,IoTapProject 40方法GetModuleCount、GetModule。