Как изменить переменную среды PATH при запуске программы установки Inno Setup?
Inno Setup позволяет устанавливать переменные среды через разделы [Registry] (путем установки раздела реестра, который соответствует переменной среды)
однако, иногда вы не просто хотите установить переменную окружения. Часто, вы хотите изменить его. Например: после установки может потребоваться добавить/удалить каталог в / из переменной среды PATH.
Как я могу изменить переменную среды PATH из InnoSetup?
5 ответов:
путь в разделе реестра, который вы дали, является значением типа
REG_EXPAND_SZ
. В качестве документации по настройке Inno для [реестр] в разделе говорится, что есть способ добавить элементы к тем:на
string
,expandsz
илиmultisz
введите значение, вы можете использовать специальную константу под названием{olddata}
в этом параметре.{olddata}
заменяется предыдущими данными значения реестра. Элемент{olddata}
константа может быть полезна, если вам нужно добавить строку существующее значение, например,{olddata};{app}
. Если значение не существует, или существующее значение не является строковым типом, то{olddata}
константа молча удалялись.таким образом, чтобы добавить к пути раздел реестра, подобный этому, можно использовать:
[Registry] Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"
что бы добавить "C:\foo" каталог к пути.
к сожалению, это будет повторяться при установке во второй раз, который также должен быть исправлен. А
Check
параметр с функцией кодированный в скрипте Pascal может быть использован для проверки того, действительно ли путь должен быть расширен:[Registry] Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"; \ Check: NeedsAddPath('C:\foo')
эта функция считывает исходное значение пути и проверяет, содержится ли в нем данный каталог. Для этого он добавляет и добавляет символы с запятой, которые используются для разделения каталогов в пути. Чтобы учесть тот факт, что искомый каталог может быть первым или последним элементом, символы с запятой добавляются и добавляются к исходному значению как ну:
[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;
обратите внимание, что вам может понадобиться, чтобы развернуть константы, прежде чем передавать их в качестве параметра в функцию проверки, см. документацию для подробностей.
удаление этого каталога из пути во время удаления может быть сделано аналогичным образом и оставлено в качестве упражнения для читателя.
вы можете использовать LegRoom.net s modpath.МКС скрипт в вашем файле сценария 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"
The
NeedsAddPath
in ответ от @mghie не проверять трейлинг\
и буквы. Исправить это.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;
у меня была та же проблема, но, несмотря на ответы выше, я закончил с пользовательским решением, и я хотел бы поделиться им с вами.
прежде всего я создал
environment.iss
файл с 2 методами-один для добавления пути к среде путь переменной и второй, чтобы удалить его:[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;
ссылки:
RegQueryStringValue
,RegWriteStringValue
теперь в главном .iss файл я мог бы включить этот файл и слушать 2 событий (подробнее о событиях вы можете узнать в Функции Событие в документации),
CurStepChanged
добавить путь после установки иCurUninstallStepChanged
, чтобы удалить его, когда пользователь удалить приложение. В приведенном ниже примере скрипта добавить / удалитьbin
каталог (относительно каталога установки):#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;
ссылки:
ExpandConstant
Примечание #1: установить шаг добавить путь только один раз (обеспечивает повторяемость установка.)
примечание #2: удалить шаг удалить только одно вхождение пути из переменной.
бонус: шаг установки флажка "добавить в переменную PATH".
чтобы добавить шаг установки с флажком "добавить в переменную PATH" определить новую задачу в
[Tasks]
раздел (установлен по умолчанию):[Tasks] Name: envPath; Description: "Add to PATH variable"
затем вы можете проверьте его в
CurStepChanged
событие:procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep = ssPostInstall) and IsTaskSelected('envPath') then EnvAddPath(ExpandConstant('{app}') +'\bin'); end;
вот полное решение проблемы, которая игнорирует корпус, проверяет наличие пути, заканчивающегося на
\
, а также расширяет константы в парам: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;