手動で行うことなく、コンポーネントライブラリパスをDelphi IDEに変更 /インストールするのが最善ですか?

StackOverflow https://stackoverflow.com/questions/6813438

質問

私はインストーラーを準備しています(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;

両方に注意してください ToRemoveToAdd. 。削除と追加リストの両方で検索パスを安全に指定できます。パスは、「削除」基準に一致する場合にのみ削除されますが、「ToAdd」リストにも含まれていません。また、に注意してください PathMatchesRemoveCriteria 関数。

おそらく、コードをInnoScript自体から直接動作するか、コードをDLLに入れてインストーラーからDLLを使用することもできます。 DLLバリアントには、Delphiで簡単にデバッグされ、Inno自体で非常に簡単なメリットがあります。 Innoバリアントには、外部依存関係がないというメリットがありますが、コードを適応してデバッグする必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top