Inno Setup Installer를 실행할 때 PATH 환경 변수를 어떻게 수정합니까?
Inno Setup에서는 [Registry] 섹션을 통해 환경 변수를 설정할 수 있습니다 (환경 변수에 해당하는 레지스트리 키 설정).
그러나 때로는 환경 변수를 설정하고 싶지 않을 때도 있습니다. 종종 수정하고 싶을 때가 있습니다. 예 : 설치시 PATH 환경 변수에 디렉토리를 추가 / 제거 할 수 있습니다.
InnoSetup 내에서 PATH 환경 변수를 어떻게 수정할 수 있습니까?
제공 한 레지스트리 키의 경로는 유형 값입니다 REG_EXPAND_SZ
. [Registry] 섹션에 대한 Inno Setup 문서에 따르면 여기에 요소를 추가하는 방법이 있습니다.
켜짐
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;
check 함수에 매개 변수로 전달하기 전에 상수를 확장해야 할 수도 있습니다. 자세한 내용은 설명서를 참조하십시오.
제거 중에 경로에서이 디렉토리를 제거하는 것은 유사한 방식으로 수행 할 수 있으며 독자를위한 연습으로 남겨 둡니다.
InnoSetup 스크립트 파일에서 LegRoom.net의 modpath.iss 스크립트를 사용할 수 있습니다 .
#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"
나는 같은 문제가 있었지만 위의 답변에도 불구하고 맞춤형 솔루션으로 끝났으며 귀하와 공유하고 싶습니다.
우선 environment.iss
두 가지 방법으로 파일을 만들었습니다. 하나는 환경의 Path 변수에 경로를 추가 하고 두 번째는 제거하는 방법입니다.
[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
Note #1: Install step add path only once (ensures repeatability of the installation).
Note #2: Uninstall step remove only one occurrence of the path from variable.
Bonus: Installation step with checkbox "Add to PATH variable".
To add installation step with checkbox "Add to PATH variable" define new task in [Tasks]
section (checked by default):
[Tasks]
Name: envPath; Description: "Add to PATH variable"
Then you can check it in CurStepChanged
event:
procedure CurStepChanged(CurStep: TSetupStep);
begin
if (CurStep = ssPostInstall) and IsTaskSelected('envPath')
then EnvAddPath(ExpandConstant('{app}') +'\bin');
end;
The NeedsAddPath
in the answer by @mghie doesn't check trailing \
and letter case. Fix it.
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;
Here is a complete solution to the problem that ignores casing, checks for existence of path ending with \
and also expands the constants in the param:
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;
'development' 카테고리의 다른 글
React Stateless 구성 요소의 이벤트 처리기 (0) | 2020.12.04 |
---|---|
Visual Studio에서 지정된 폴더 또는 파일 형식으로 검색을 제한 하시겠습니까? (0) | 2020.12.04 |
이메일 주소에 영숫자가 아닌 문자를 포함 할 수 있습니까? (0) | 2020.12.04 |
리소스 ID의 정수 배열 만들기 (0) | 2020.12.04 |
개체를 쿼리 문자열 형식으로 직렬화하는 방법은 무엇입니까? (0) | 2020.12.04 |