如何最好地将组件库路径修改/安装到DelphiIDE中,而无需手动执行?
我正在准备一个安装程序()来将我的组件包安装到Delphi XE中,而不必在IDE中手动修改 我需要修改Delphi库路径,例如删除其中的一部分(例如,如何最好地将组件库路径修改/安装到DelphiIDE中,而无需手动执行?,delphi,path,components,library-path,Delphi,Path,Components,Library Path,我正在准备一个安装程序()来将我的组件包安装到Delphi XE中,而不必在IDE中手动修改 我需要修改Delphi库路径,例如删除其中的一部分(例如,xxx;myolpath;yyy),并插入一个新路径,xxxx;MyNewPath;yyyy。有没有一种更好的方法来实现这一点,或者我必须编写一个实用程序来实现这一点 谢谢修改路径是基本的字符串操作:从注册表读取当前路径,根据需要进行操作,然后写回 您可以编写一个Inno设置脚本函数,这样就不会有任何外部依赖关系。或者编写一个从Inno安装程序脚
xxx;myolpath;yyy
),并插入一个新路径,xxxx;MyNewPath;yyyy
。有没有一种更好的方法来实现这一点,或者我必须编写一个实用程序来实现这一点
谢谢修改路径是基本的字符串操作:从注册表读取当前路径,根据需要进行操作,然后写回 您可以编写一个Inno设置脚本函数,这样就不会有任何外部依赖关系。或者编写一个从Inno安装程序脚本中使用的Delphi DLL,以便更容易调试
编辑 这是我在生产中实际使用的例程的一个修改版本。它将从
搜索路径
注册表值或浏览路径
(任何其他路径)中读取整个路径列表,可能会删除一些路径,如果它们不存在,则添加一些路径
procedure UpdateDelphiPaths(const RegistryKey, RegistryValue: string; PathsToRemove, PathsToAdd: TStrings);
var R:TRegistry;
SKeys:TStringList;
Found:Boolean;
Updated:Boolean;
i,j:Integer;
s:string;
R_Globals:TRegistry;
// This function normalises paths in comparasions
function PrepPathForComparasion(const Path:string):string;
begin
if Path = '' then Result := '\'
else
if Path[Length(Path)] = '\' then
Result := LowerCase(Path)
else
Result := LowerCase(Path) + '\';
end;
function PathMatchesRemoveCriteria(const Path:string): Boolean;
var i:Integer;
begin
// This needs to be addapted to match your criteria!
for i:=0 to PathsToRemove.Count-1 do
if AnsiPos(PathsToRemove[i], Path) <> 0 then
Exit(True);
Result := False;
end;
begin
R := TRegistry.Create;
try
R.RootKey := HKEY_CURRENT_USER;
if R.OpenKey(RegistryKey + '\Library', False) then
if R.ValueExists(RegistryValue) then
begin
SKeys := TStringList.Create;
try
SKeys.Delimiter := ';';
SKeys.StrictDelimiter := True;
SKeys.DelimitedText := R.ReadString(RegistryValue);
Updated := False;
// Look at all the paths in the PathsToAdd list, if any one's missing add it to the list and mark
// "Updated".
for i:=0 to PathsToAdd.Count-1 do
begin
Found := False;
for j:=0 to SKeys.Count-1 do
if LowerCase(Trim(SKeys[j])) = LowerCase(Trim(PathsToAdd[i])) then
Found := True;
if not Found then
begin
SKeys.Add(PathsToAdd[i]);
Updated := True;
end;
end;
// Look at every single path in the current list, if it's not in the "PathsToAdd" and it matches
// a name in "PathsToRemove", drop it and mark "Updated"
i := 0;
while i < SKeys.Count do
begin
if PathMatchesRemoveCriteria(SKeys[i]) then
begin
// Path matches remove criteria! It only gets removed if it's not actually present in
// PathsToAdd
Found := False;
for j:=0 to PathsToAdd.Count-1 do
begin
if PrepPathForComparasion(SKeys[i]) = PrepPathForComparasion(PathsToAdd[j]) then
Found := True;
end;
if not Found then
begin
SKeys.Delete(i);
Updated := True;
end
else
Inc(i);
end
else
Inc(i);
end;
// If I've updated the SKeys in any way, push changes back to registry and force updates
if Updated then
begin
s := SKeys[0];
for i:=1 to SKeys.Count-1 do
if SKeys[i] <> '' then
begin
s := s + ';' + SKeys[i];
end;
R.WriteString(RegistryValue, s);
// Force delphi to re-load it's paths.
R_Globals := TRegistry.Create;
try
R_Globals.OpenKey(RegistryKey + '\Globals', True);
R_Globals.WriteString('ForceEnvOptionsUpdate', '1');
finally R_Globals.Free;
end;
end;
finally SKeys.Free;
end;
end;
finally R.Free;
end;
end;
请注意ToRemove
和ToAdd
。我可以在删除列表和添加列表中安全地指定搜索路径:仅当路径符合“删除”条件时才会删除,但不在“ToAdd”列表中。还要注意PathMatchesRemoveCriteria
函数
您可以直接从InnoScript本身修改代码,或者将代码放入DLL并使用安装程序提供的DLL。DLL变量的优点是易于在Delphi中调试,并且在Inno本身上非常容易;Inno变体的优点是没有外部依赖项,但代码需要调整和调试。库路径是注册表中的一个子项;请考虑可能有不止一个注册表项(与-R命令行交换机一起传递给BDS可执行文件)。安装程序可能应该枚举所有现有的注册表项,并提供一个复选框或类似的界面,以便用户可以选择应该修改哪些注册表项。如果您正在做我认为您正在做的事情(在innosetup中创建组件安装程序),这可能会成为值得写一篇小文章并在你的博客上发布的东西。
var ToRemove, ToAdd: TStringList;
begin
ToRemove := TStringList.Create;
try
ToAdd := TStringList.Create;
try
ToRemove.Add('LibraryName\Source');
ToAdd.Add('C:\LibraryName\Source');
UpdateDelphiPaths('Software\CodeGear\BDS\7.0', 'Test Path', ToRemove, ToAdd);
finally ToAdd.Free;
end;
finally ToRemove.Free;
end;
end;