How do I modify the PATH environment variable when running an Inno Setup Installer?

后端 未结 6 605
逝去的感伤
逝去的感伤 2020-11-28 03:31

Inno Setup lets you set environment variables via the [Registry] sections (by setting registry key which correspond to environment variable)

However, sometimes you d

6条回答
  •  萌比男神i
    2020-11-28 04:02

    I want to thank everyone for their contributions to this question. I've incorporated about 95% of the code posted by Wojciech Mleczek into my app's installer. I do have some corrections to that code that may prove useful to others. My changes:

    • Renamed formal argument Path to instlPath. Cuts down on multiple uses of "Path" in code (easier to read, IMO).

    • When installing/uninstalling, add an existence check for an instlPath that ends with \;.

    • During installation, don't double up ; in the current %PATH%.

    • Handle missing or empty %PATH% during installation.

    • During uninstall, make sure that a starting index of 0 is not passed to Delete().

    Here's my updated version of EnvAddPath():

    const EnvironmentKey = 'Environment';
    
    procedure EnvAddPath(instlPath: string);
    var
        Paths: string;
    begin
        { Retrieve current path (use empty string if entry not exists) }
        if not RegQueryStringValue(HKEY_CURRENT_USER, EnvironmentKey, 'Path', Paths) then
            Paths := '';
    
        if Paths = '' then
            Paths := instlPath + ';'
        else
        begin
            { Skip if string already found in path }
            if Pos(';' + Uppercase(instlPath) + ';',  ';' + Uppercase(Paths) + ';') > 0 then exit;
            if Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';') > 0 then exit;
    
            { Append App Install Path to the end of the path variable }
            Log(Format('Right(Paths, 1): [%s]', [Paths[length(Paths)]]));
            if Paths[length(Paths)] = ';' then
                Paths := Paths + instlPath + ';'  { don't double up ';' in env(PATH) }
            else
                Paths := Paths + ';' + instlPath + ';' ;
        end;
    
        { Overwrite (or create if missing) path environment variable }
        if RegWriteStringValue(HKEY_CURRENT_USER, EnvironmentKey, 'Path', Paths)
        then Log(Format('The [%s] added to PATH: [%s]', [instlPath, Paths]))
        else Log(Format('Error while adding the [%s] to PATH: [%s]', [instlPath, Paths]));
    end;
    

    And an updated version of EnvRemovePath():

    procedure EnvRemovePath(instlPath: string);
    var
        Paths: string;
        P, Offset, DelimLen: Integer;
    begin
        { Skip if registry entry not exists }
        if not RegQueryStringValue(HKEY_CURRENT_USER, EnvironmentKey, 'Path', Paths) then
            exit;
    
        { Skip if string not found in path }
        DelimLen := 1;     { Length(';') }
        P := Pos(';' + Uppercase(instlPath) + ';', ';' + Uppercase(Paths) + ';');
        if P = 0 then
        begin
            { perhaps instlPath lives in Paths, but terminated by '\;' }
            DelimLen := 2; { Length('\;') }
            P := Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';');
            if P = 0 then exit;
        end;
    
        { Decide where to start string subset in Delete() operation. }
        if P = 1 then
            Offset := 0
        else
            Offset := 1;
        { Update path variable }
        Delete(Paths, P - Offset, Length(instlPath) + DelimLen);
    
        { Overwrite path environment variable }
        if RegWriteStringValue(HKEY_CURRENT_USER, EnvironmentKey, 'Path', Paths)
        then Log(Format('The [%s] removed from PATH: [%s]', [instlPath, Paths]))
        else Log(Format('Error while removing the [%s] from PATH: [%s]', [instlPath, Paths]));
    end;
    

提交回复
热议问题