Wie können Sie einen Komponentenbibliothekspfad am besten in die Delphi -IDE ändern / installieren, ohne es manuell zu tun?

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

Frage

Ich bereite einen Installateur vor (Inno Setup) So installieren Sie mein Komponentenpaket in Delphi XE, ohne manuell in der IDE fummeln zu müssen.

Ich muss den Pfad der Delphi -Bibliothek ändern, um einen Teil davon zu löschen (zum Beispiel,, xxx;MyOldPath;yyy) und einen neuen Pfad einfügen, xxxx;MyNewPath;yyyy. Gibt es eine bevorzugte Möglichkeit, dies zu tun, oder muss ich ein Dienstprogramm schreiben, um dies zu tun?

Vielen Dank

War es hilfreich?

Lösung

Das Ändern des Pfades ist eine grundlegende String -Manipulation: Sie lesen den aktuellen Pfad aus der Registrierung, manipulieren Sie ihn an Ihren Bedürfnissen und schreiben ihn zurück.

Sie können wahrscheinlich eine Inno -Setup -Skriptfunktion schreiben, damit Sie keine externen Abhängigkeiten haben. Oder schreiben Sie eine Delphi -DLL, die aus dem Skript von Inno Setup verwendet wird, damit es einfacher ist, zu debuggen.


Bearbeiten

Hier ist eine modifizierte Version einer Routine, die ich tatsächlich in der Produktion verwende. Es wird die gesamte Liste der Pfade von beiden lesen Search Path Registrierungswert oder der Browsing Path (Jeder andere Weg für diese Angelegenheit), entfernen Sie möglicherweise einige Pfade und fügen Sie einige Pfade hinzu, wenn sie noch nicht existieren.

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;

Aus Delphi Code kann ich die Routine wie diese aufrufen, um sicherzustellen, dass der neueste Suchpfad zu einer bestimmten Bibliothek installiert ist:

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;

Beachten Sie beide ToRemove und ToAdd. Ich kann sicher einen Suchpfad in Entfernen und Hinzufügen von Listen angeben: Die Pfade werden nur entfernt, wenn sie die Kriterien "entfernen" übereinstimmen, aber nicht auch in der Liste "Toadd". Beachten Sie auch die PathMatchesRemoveCriteria Funktion.

Sie können den Code wahrscheinlich so ändern, dass sie direkt aus dem InnoScript selbst arbeiten, oder den Code in eine DLL einfügen und die DLL vom Installateur verwenden. Die DLL -Variante hat den Verdienst, in Delphi leicht debuggen zu werden und inno selbst sehr einfach. Die Inno -Variante hat den Verdienst, keine externen Abhängigkeiten zu haben, aber der Code müsste angepasst und debuggen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top