La meilleure façon de modifier / installer un chemin bibliothèque de composants dans l'IDE Delphi sans le faire manuellement?

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

Question

Je prépare un programme d'installation ( Inno Setup ) pour installer mon paquet composant dans Delphi XE sans ayant pour violon manuellement dans l'EDI.

Je dois modifier le chemin de la bibliothèque Delphi, par exemple pour une partie de suppression de celui-ci (par exemple, xxx;MyOldPath;yyy) et insérez un nouveau chemin, xxxx;MyNewPath;yyyy. Est-il un moyen privilégié de faire ceci ou devrai-je écrire un utilitaire pour le faire?

Merci

Était-ce utile?

La solution

Modification du chemin est la manipulation de chaînes de base. Lire le chemin actuel du registre, manipuler en fonction de vos besoins, écrire retour

Vous pouvez probablement écrire une fonction de script d'installation Inno de sorte que vous n'avez pas de dépendances externes. Ou écrire une DLL Delphi qui est utilisé à partir du script de Inno Setup il sera plus facile de débogage.


Modifier

Voici une version modifiée d'une routine que je utilise en fait la production. Il va lire la liste complète des chemins de soit la valeur de Registre de Search Path ou Browsing Path (tout autre chemin pour cette matière), supprimer éventuellement des chemins, et ajouter des chemins si elles existent déjà.

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;

A partir du code Delphi je peux appeler la routine comme ça, pour vous assurer que le dernier chemin de recherche à une bibliothèque donnée est installé:

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;

Avis à la fois la ToRemove et ToAdd. Je peux en toute sécurité spécifier un chemin de recherche à la fois supprimer et ajouter des listes: Les chemins ne sont supprimés si elles correspondent à des critères de « Supprimer », mais ne sont pas aussi dans la liste « ToAdd ». Notez également la fonction PathMatchesRemoveCriteria.

Vous pouvez modifier probablement le code de travail directement à partir du InnoScript lui-même, ou vous pouvez mettre le code dans une DLL et utiliser la DLL de l'installateur. La variante de DLL a le mérite d'être facilement à Delphes et débogué très facile sur Inno lui-même; La variante Inno a le mérite de ne pas avoir des dépendances externes, mais le code devrait être adapté et débogué.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top