environment-variables inno-setup

environment variables - ¿Cómo modifico la variable de entorno PATH cuando ejecuto un instalador Inno Setup?



environment-variables inno-setup (5)

Inno Setup le permite configurar variables de entorno a través de las secciones [Registro] (configurando la clave de registro que corresponde a la variable de entorno)

Sin embargo, a veces no solo quieres establecer una variable de entorno. A menudo, quieres modificarlo. Por ejemplo: después de la instalación, uno puede desear agregar / eliminar un directorio a / desde la variable de entorno PATH.

¿Cómo puedo modificar la variable de entorno PATH desde InnoSetup?


Aquí hay una solución completa al problema que ignora la carcasa, verifica la existencia de una ruta que termine con / y también expande las constantes en el parámetro:

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;


El NeedsAddPath en la respuesta por @mghie no comprueba el caso de / y la letra de seguimiento. Arreglalo.

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;


Puede usar el script modpath.iss de modpath.iss en su archivo 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"


Tuve el mismo problema, pero a pesar de las respuestas anteriores, terminé con una solución personalizada y me gustaría compartirla con usted.

En primer lugar, he creado el archivo environment.iss con 2 métodos, uno para agregar la ruta a la variable Path del entorno y el segundo para eliminarlo:

[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;

Referencia: RegQueryStringValue , RegWriteStringValue

Ahora, en el archivo .iss principal, podría incluir este archivo y escuchar los 2 eventos (más sobre eventos que puede aprender en la sección Funciones de eventos en la documentación), CurStepChanged para agregar una ruta después de la instalación y CurUninstallStepChanged para eliminarla cuando el usuario desinstala una aplicación. En el siguiente script de ejemplo, agregue / elimine el directorio bin (relativo al directorio de instalación):

#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;

Referencia: ExpandConstant

Nota n. ° 1 : Instale el paso agregar ruta una sola vez (garantiza la repetibilidad de la instalación).

Nota # 2 : el paso de desinstalación elimina solo una aparición de la ruta de la variable.

Bonus : Paso de instalación con la casilla de verificación "Agregar a variable PATH" .

Para agregar el paso de instalación con la casilla de verificación "Agregar a variable PATH", defina una nueva tarea en la sección [Tasks] (marcada de forma predeterminada):

[Tasks] Name: envPath; Description: "Add to PATH variable"

Entonces puedes comprobarlo en el evento CurStepChanged :

procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep = ssPostInstall) and IsTaskSelected(''envPath'') then EnvAddPath(ExpandConstant(''{app}'') +''/bin''); end;


La ruta en la clave de registro que dio es un valor de tipo REG_EXPAND_SZ . Como la documentación de Inno Setup para la sección [Registro] indica que hay una manera de agregar elementos a esos:

En una string , expandsz o valor de tipo multisz , puede usar una constante especial llamada {olddata} en este parámetro. {olddata} se reemplaza con los datos anteriores del valor de registro. La constante {olddata} puede ser útil si necesita agregar una cadena a un valor existente, por ejemplo, {olddata};{app} . Si el valor no existe o el valor existente no es un tipo de cadena, la constante {olddata} se elimina silenciosamente.

Entonces, para agregar a la ruta se puede usar una sección de registro similar a esta:

[Registry] Root: HKLM; Subkey: "SYSTEM/CurrentControlSet/Control/Session Manager/Environment"; / ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:/foo"

que agregaría el directorio "C: / foo" a la ruta.

Lamentablemente, esto se repetirá cuando instale una segunda vez, lo que también debería solucionarse. Se puede usar un parámetro de Check con una función codificada en el script de Pascal para verificar si la ruta realmente necesita expandirse:

[Registry] Root: HKLM; Subkey: "SYSTEM/CurrentControlSet/Control/Session Manager/Environment"; / ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:/foo"; / Check: NeedsAddPath(''C:/foo'')

Esta función lee el valor de la ruta original y comprueba si el directorio dado ya está contenido en ella. Para ello, se antepone y agrega caracteres de punto y coma que se utilizan para separar directorios en la ruta. Para tener en cuenta el hecho de que el directorio buscado puede ser el primer o último elemento, los caracteres de punto y coma se añaden y se agregan al valor original también:

[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;

Tenga en cuenta que es posible que necesite expandir las constantes antes de pasarlas como parámetro a la función de verificación; consulte la documentación para obtener más detalles.

La eliminación de este directorio de la ruta durante la desinstalación se puede realizar de manera similar y se deja como un ejercicio para el lector.