2010-07-21 2 views
54

Inno Setup에서는 환경 변수에 해당하는 레지스트리 키를 설정하여 [Registry] 섹션을 통해 환경 변수를 설정할 수 있습니다.Inno 설치 프로그램을 실행할 때 PATH 환경 변수를 어떻게 수정합니까?

그러나 때때로 환경 변수를 설정하기 만하면됩니다. 종종 그것을 수정하고 싶습니다. 예 : 설치시, PATH 환경 변수에 디렉토리를 추가/제거 할 수 있습니다.

InnoSetup 내에서 PATH 환경 변수를 어떻게 수정할 수 있습니까?

답변

71

입력 한 레지스트리 키의 경로는 REG_EXPAND_SZ 유형의 값입니다. [레지스트리] 섹션 상태에 대한 이노 설치 설명서로 사람들에게 요소를 추가하는 방법이있다하십시오 string, expandsz, 또는 multisz 유형 값에

을, 당신은에 {olddata}라는 특별한 상수를 사용할 수있다 이 매개 변수. {olddata}은 레지스트리 값의 이전 데이터로 바뀝니다. {olddata} 상수는 문자열을 기존 값에 추가해야하는 경우 유용 할 수 있습니다 (예 : {olddata};{app}). 값이 존재하지 않거나 기존 값이 문자열 유형이 아니면 {olddata} 상수는 자동으로 제거됩니다.

그래서이 유사한 레지스트리 섹션을 사용할 수있다 경로에 추가 할 : 경로에 디렉토리은 "\ foo는 C"를 추가 할

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

합니다.

두 번째로 설치할 때이 문제가 반복 될 수 있으며 수정해야합니다. 지정된 디렉토리가 이미 포함되어 있는지 여부를

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

이 기능은 원래의 경로 값과 검사를 읽 파스칼 스크립트로 코딩 기능을 가진 Check 매개 변수는 경로가 참으로 확장 할 필요가 않습니다 여부를 확인하는 데 사용할 수 있습니다 . 이렇게하려면 경로의 디렉토리를 구분하는 데 사용되는 세미콜론 (;)을 앞에 추가하고 추가합니다. 당신은 당신이 그들을 통과하기 전에 상수를 확장해야 할 수도 있습니다

[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 함수에 전달하려면 자세한 내용은 설명서를 참조하십시오.

제거 중에 경로에서이 디렉토리를 제거하는 작업은 유사한 방식으로 수행 할 수 있으며 독자의 연습 과제로 남겨 두었습니다.

+1

간단히 말해서 {olddata }'를 Check 함수에 추가하면 코드에서 값을 다시 읽을 필요가 없습니다. (어쩌면 당신은 할 수 있습니다 - 나는 시도하지 않았습니다);) –

+3

또 다른 것은 경로가있을 수 있지만 다른 대소 문자를 사용하는 것입니다 (쉽게 'UpperCase' 또는 somesuch 함수를 사용하여 수정 됨). 또는 더 나쁘면 8.3 경로 이름을 사용하십시오 (예 : "C : \ Progra ~ 1 \ MyProg") 또는 환경 변수 (예 : "% programfiles % \ MyProg"). 그것들을 탐지하는 것은 악몽 일 것입니다 ... –

+1

프로그램이 제거 될 때 어떨까요? PATH 환경 변수에서 경로를 어떻게 제거 하시겠습니까? –

6

the answer by @mghie에있는 NeedsAddPath은 후행 \ 및 대소 문자를 확인하지 않습니다. 고쳐.

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; 
+3

'C : \ foo'대신 변수를 사용하려면 어떻게해야합니까? NeedsAddPath ('{app}')를 시도했지만 작동하지 않습니다. 이미 경로가 종료되었지만 연결 만합니다. 제발 조언 해 줄래? –

+1

위의 답변에 그냥 다른 사람에게 유용 할 수 있습니다 : 당신은'ExpandConstant()'함수를 사용해야합니다. – Jack

+0

잭 감사합니다. 그러나 NeedsAddPath ('{app} \ MoreDirectoriesHere') 예제를 보길 원합니다. – vezenkov

14

LegRoom을 사용할 수 있습니다.당신의 InnoSetup 스크립트 파일 순의 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" 
1

\로 끝나는 경로의 존재 케이스, 검사를 무시 문제에 대한 완벽한 솔루션이며, 또한 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; 
+0

여기에 문제가 있음을 확인하십시오 : ';'사례가 발견 된 경우에만 ''\ ''사례를 확인합니다. – Stewart

2

나는 똑같은 문제가 있었지만 위의 대답에도 불구하고 사용자 지정 솔루션으로 끝났으며 사용자와 공유하고 싶습니다.

나는이 방법과 environment.iss 파일을 생성 한 모든

첫째 - 환경의 경로에 경로를 추가 한 변수와 두 번째는 그것을 제거합니다 :

[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 개의 이벤트 (문서의 Event Functions 섹션에서 배울 수있는 이벤트에 대한 정보), 설치 후 경로를 추가하는 CurStepChangedCurUninstallStepChanged 사용자가 응용 프로그램을 제거 할 때 제거하십시오.

#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가 : 설치 단계를 한 번만 경로를 추가합니다 (설치의 재현성을 보장 예제 스크립트가 추가 아래에서/(설치 디렉토리에 상대적)을 bin 디렉토리를 제거).

참고 # 2 : 제거 단계에서는 변수에서 경로가 한 번만 제거됩니다.

보너스 : 확인란을 사용하는 설치 단계 "PATH 변수에 추가".

Inno Setup - Add to PATH variable

확인란 와 설치 단계를 추가하려면 "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;