手動で行うことなく、コンポーネントライブラリパスをDelphi IDEに変更 /インストールするのが最善ですか?
-
25-10-2019 - |
質問
私はインストーラーを準備しています(Innoセットアップ)IDEを手動でフィドルすることなく、コンポーネントパッケージをDelphi XEにインストールします。
たとえば、その一部を削除するために、Delphiライブラリパスを変更する必要があります(たとえば、 xxx;MyOldPath;yyy
)そして、新しいパスを挿入し、 xxxx;MyNewPath;yyyy
. 。これを行うための好ましい方法はありますか、それともそれを行うためにユーティリティを書く必要がありますか?
ありがとう
解決
パスの変更は基本的な文字列操作です。レジストリから現在のパスを読み、ニーズに合わせて操作し、書き戻します。
おそらく、Innoセットアップスクリプト関数を書くことができ、外部依存関係がないことです。または、Innoセットアップのスクリプトから使用されるDelphi DLLを作成して、デバッグが簡単になります。
編集
これは、私が実際に生産で使用しているルーチンの変更されたバージョンです。どちらかのパスのリスト全体を読み取ります Search Path
レジストリ値または Browsing Path
(そのことについて他のパス)、潜在的にいくつかのパスを削除し、それらがまだ存在しない場合はいくつかのパスを追加します。
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;
Delphiコードから、このようなルーチンを呼び出すことができます。特定のライブラリへの最新の検索パスがインストールされていることを確認できます。
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;
両方に注意してください ToRemove
と ToAdd
. 。削除と追加リストの両方で検索パスを安全に指定できます。パスは、「削除」基準に一致する場合にのみ削除されますが、「ToAdd」リストにも含まれていません。また、に注意してください PathMatchesRemoveCriteria
関数。
おそらく、コードをInnoScript自体から直接動作するか、コードをDLLに入れてインストーラーからDLLを使用することもできます。 DLLバリアントには、Delphiで簡単にデバッグされ、Inno自体で非常に簡単なメリットがあります。 Innoバリアントには、外部依存関係がないというメリットがありますが、コードを適応してデバッグする必要があります。