Inno Setupでは、[Registry]セクションを介して環境変数を設定できます(環境変数に対応するレジストリキーを設定することにより)
ただし、環境変数を設定したくない場合があります。多くの場合、あなたはそれを修正したい。たとえば、インストール時に、PATH環境変数にディレクトリを追加したり、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」ディレクトリを追加します。
残念ながら、2回目のインストール時にこれが繰り返されますが、これも修正する必要があります。パスカルスクリプトでコード化された関数を持つCheck
パラメーターを使用して、パスを実際に展開する必要があるかどうかを確認できます。
[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;
チェック関数にパラメータとして渡す前に定数を展開する必要がある場合があることに注意してください。詳細についてはドキュメントを参照してください。
アンインストール中にこのディレクトリをパスから削除することも同様の方法で実行でき、読者の演習として残されます。
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
ファイルには2つのメソッドがあります。1つは環境のPath変数にパスを追加し、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つのイベント(ドキュメントの Event Functions セクションで学習できるイベントの詳細)をリッスンできます。インストール後にパスを追加するには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:インストール手順はパスを1回だけ追加します(インストールの再現性を確保します)。
注#2:アンインストール手順は、変数からパスの1つの出現のみを削除します。
ボーナス:チェックボックス「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;
@ 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;
大文字小文字を無視し、\
で終わるパスの存在をチェックし、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;