Inno Setup vous permet de définir des variables d'environnement via les sections [Registry] (en définissant une clé de registre qui correspond à la variable d'environnement)
Cependant, parfois, vous ne voulez pas simplement définir une variable d'environnement. Souvent, vous voulez le modifier. Par exemple: lors de l'installation, on peut vouloir ajouter/supprimer un répertoire à/de la variable d'environnement PATH.
Comment puis-je modifier la variable d'environnement PATH à partir d'InnoSetup?
Le chemin d'accès dans la clé de registre que vous avez indiquée est une valeur de type REG_EXPAND_SZ
. Comme l'indique la documentation d'Inno Setup pour la section [Registry], il existe un moyen d'ajouter des éléments à ceux-ci:
Sur une valeur de type
string
,expandsz
oumultisz
, vous pouvez utiliser une constante spéciale appelée{olddata}
dans ce paramètre.{olddata}
est remplacé par les données précédentes de la valeur de registre. Le{olddata}
constant peut être utile si vous devez ajouter une chaîne à une valeur existante, par exemple,{olddata};{app}
. Si la valeur n'existe pas ou si la valeur existante n'est pas un type de chaîne, le{olddata}
constante est supprimée en silence.
Donc, pour ajouter au chemin une section de registre similaire à celle-ci peut être utilisée:
[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"
ce qui ajouterait le répertoire "C:\foo" au chemin.
Malheureusement, cela se répéterait lors de la deuxième installation, ce qui devrait également être corrigé. Un paramètre Check
avec une fonction codée en script Pascal peut être utilisé pour vérifier si le chemin a bien besoin d'être développé:
[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"; \
Check: NeedsAddPath('C:\foo')
Cette fonction lit la valeur du chemin d'origine et vérifie si le répertoire donné y est déjà contenu. Pour ce faire, il ajoute et ajoute des caractères point-virgule qui sont utilisés pour séparer les répertoires du chemin. Pour tenir compte du fait que le répertoire recherché peut être le premier ou le dernier élément, les caractères point-virgule sont également ajoutés et ajoutés à la valeur d'origine:
[Code]
function NeedsAddPath(Param: string): boolean;
var
OrigPath: string;
begin
if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', OrigPath)
then begin
Result := True;
exit;
end;
{ look for the path with leading and trailing semicolon }
{ Pos() returns 0 if not found }
Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0;
end;
Notez que vous devrez peut-être développer des constantes avant de les passer en paramètre à la fonction de vérification, consultez la documentation pour plus de détails.
La suppression de ce répertoire du chemin lors de la désinstallation peut être effectuée de la même manière et est laissée en exercice au lecteur.
Vous pouvez utiliser le script modpath.iss de LegRoom.net dans votre fichier de script InnoSetup:
#define MyTitleName "MyApp"
[Setup]
ChangesEnvironment=yes
[CustomMessages]
AppAddPath=Add application directory to your environmental path (required)
[Files]
Source: "install\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs;
[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyTitleName}}"; Filename: "{uninstallexe}"; Comment: "Uninstalls {#MyTitleName}"
Name: "{group}\{#MyTitleName}"; Filename: "{app}\{#MyTitleName}.EXE"; WorkingDir: "{app}"; AppUserModelID: "{#MyTitleName}"; Comment: "Runs {#MyTitleName}"
Name: "{commondesktop}\{#MyTitleName}"; Filename: "{app}\{#MyTitleName}.EXE"; WorkingDir: "{app}"; AppUserModelID: "{#MyTitleName}"; Comment: "Runs {#MyTitleName}"
[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}"
[Tasks]
Name: modifypath; Description:{cm:AppAddPath};
[Code]
const
ModPathName = 'modifypath';
ModPathType = 'system';
function ModPathDir(): TArrayOfString;
begin
setArrayLength(Result, 1)
Result[0] := ExpandConstant('{app}');
end;
#include "modpath.iss"
J'ai eu le même problème mais malgré les réponses ci-dessus, je me suis retrouvé avec une solution personnalisée et je voudrais la partager avec vous.
Tout d'abord, j'ai créé le environment.iss
fichier avec 2 méthodes - une pour ajouter un chemin à la variable Path de l'environnement et la seconde pour la supprimer:
[Code]
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
procedure EnvAddPath(Path: string);
var
Paths: string;
begin
{ Retrieve current path (use empty string if entry not exists) }
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
then Paths := '';
{ Skip if string already found in path }
if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit;
{ App string to the end of the path variable }
Paths := Paths + ';'+ Path +';'
{ Overwrite (or create if missing) path environment variable }
if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
then Log(Format('The [%s] added to PATH: [%s]', [Path, Paths]))
else Log(Format('Error while adding the [%s] to PATH: [%s]', [Path, Paths]));
end;
procedure EnvRemovePath(Path: string);
var
Paths: string;
P: Integer;
begin
{ Skip if registry entry not exists }
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then
exit;
{ Skip if string not found in path }
P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';');
if P = 0 then exit;
{ Update path variable }
Delete(Paths, P - 1, Length(Path) + 1);
{ Overwrite path environment variable }
if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
then Log(Format('The [%s] removed from PATH: [%s]', [Path, Paths]))
else Log(Format('Error while removing the [%s] from PATH: [%s]', [Path, Paths]));
end;
Référence: RegQueryStringValue
, RegWriteStringValue
Maintenant, dans le fichier .iss principal, je pourrais inclure ce fichier et écouter les 2 événements (plus d'informations sur les événements que vous pouvez apprendre dans la section Fonctions d'événement dans la documentation), CurStepChanged
pour ajouter un chemin après l'installation et CurUninstallStepChanged
pour le supprimer lorsque l'utilisateur désinstalle une application. Dans l'exemple de script ci-dessous, ajoutez/supprimez le répertoire bin
(par rapport au répertoire d'installation):
#include "environment.iss"
[Setup]
ChangesEnvironment=true
; More options in setup section as well as other sections like Files, Components, Tasks...
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall
then EnvAddPath(ExpandConstant('{app}') +'\bin');
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall
then EnvRemovePath(ExpandConstant('{app}') +'\bin');
end;
Référence: ExpandConstant
Remarque # 1 : Étape d'installation ajouter le chemin d'accès une seule fois (assure la répétabilité de l'installation).
Remarque n ° 2 : l'étape de désinstallation supprime une seule occurrence du chemin de la variable.
Bonus : Étape d'installation avec la case à cocher "Ajouter à la variable PATH".
Pour ajouter une étape d'installation avec la case à cocher "Ajouter à la variable PATH" définir une nouvelle tâche dans [Tasks]
section (cochée par défaut):
[Tasks]
Name: envPath; Description: "Add to PATH variable"
Ensuite, vous pouvez le vérifier dans l'événement CurStepChanged
:
procedure CurStepChanged(CurStep: TSetupStep);
begin
if (CurStep = ssPostInstall) and IsTaskSelected('envPath')
then EnvAddPath(ExpandConstant('{app}') +'\bin');
end;
Le NeedsAddPath
in la réponse de @mghie ne vérifie pas le _ \
et la casse des lettres. Répare le.
function NeedsAddPath(Param: string): boolean;
var
OrigPath: string;
begin
if not RegQueryStringValue(
HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', OrigPath)
then begin
Result := True;
exit;
end;
{ look for the path with leading and trailing semicolon }
{ Pos() returns 0 if not found }
Result :=
(Pos(';' + UpperCase(Param) + ';', ';' + UpperCase(OrigPath) + ';') = 0) and
(Pos(';' + UpperCase(Param) + '\;', ';' + UpperCase(OrigPath) + ';') = 0);
end;
Voici une solution complète au problème qui ignore la casse, vérifie l'existence d'un chemin se terminant par \
et développe également les constantes dans le paramètre:
function NeedsAddPath(Param: string): boolean;
var
OrigPath: string;
ParamExpanded: string;
begin
//expand the setup constants like {app} from Param
ParamExpanded := ExpandConstant(Param);
if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', OrigPath)
then begin
Result := True;
exit;
end;
// look for the path with leading and trailing semicolon and with or without \ ending
// Pos() returns 0 if not found
Result := Pos(';' + UpperCase(ParamExpanded) + ';', ';' + UpperCase(OrigPath) + ';') = 0;
if Result = True then
Result := Pos(';' + UpperCase(ParamExpanded) + '\;', ';' + UpperCase(OrigPath) + ';') = 0;
end;