Il modo migliore per modificare / installare un percorso libreria di componenti in Delphi IDE senza farlo manualmente?

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

Domanda

Sto preparando un installer ( Inno Setup) per installare il mio pacchetto di componenti in Delphi XE senza dover armeggiare manualmente nell'IDE.

Ho bisogno di modificare il percorso della libreria di Delphi, per esempio per una parte di eliminazione di esso (ad esempio, xxx;MyOldPath;yyy) e inserire un nuovo percorso, xxxx;MyNewPath;yyyy. C'è un modo migliore di fare questo o dovrò scrivere un programma di utilità per farlo?

Grazie

È stato utile?

Soluzione

La modifica del percorso è manipolazione di stringhe di base:. Si legge il percorso della corrente dal Registro di sistema, manipolarla in base alle proprie esigenze, scrivere di nuovo

È probabilmente può scrivere una funzione di script Inno Setup in modo da non avere dipendenze esterne. O scrivere una DLL Delphi che viene utilizzato dallo script di Inno Setup in modo sarà più facile per eseguire il debug.


Modifica

Ecco una versione modificata di una routine realtà sto utilizzando in produzione. Sarà leggere l'intero elenco dei percorsi da entrambi il valore del Registro Search Path o Browsing Path (qualsiasi altro percorso è per questo), rimuovere potenzialmente alcuni percorsi, e aggiungere alcuni percorsi se non esistono già.

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;

Da codice Delphi posso chiamare la routine come questo, per assicurarsi l'ultimo percorso di ricerca per una data libreria è installato:

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;

Avviso sia il ToRemove e ToAdd. Posso specificare in modo sicuro un percorso di ricerca sia nel rimuovere e aggiungere liste: I percorsi vengono rimossi solo se corrispondono criteri "Rimuovi", ma non sono anche nella lista "toadd". Da notare anche la funzione PathMatchesRemoveCriteria.

È probabilmente può modificare il codice per lavoro direttamente dal InnoScript stesso, o si può mettere il codice in una DLL e utilizzare la DLL dal programma di installazione. La variante DLL ha il merito di essere facilmente debug in Delphi e molto facile su Inno stessa; La variante Inno ha il merito di non avere dipendenze esterne, ma dovrebbe essere adattato e debug del codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top