Search code examples
windowsenvironment-variablesinstallationinno-setuppascalscript

Inno Setup - Remove path from PATH environment variable while uninstalling a program


I wrote an Inno Setup script which install a program and update the PATH environment variable with the directory in which the program in installed.

I want to update the PATH environment variable, to restore its previous installation status.

The installation path is chosen by the user while the installer is running.

This is the script, which uses code from How do I modify the PATH environment variable when running an Inno Setup Installer?

[Setup]
ChangesEnvironment=yes

[Registry]
Root: HKLM; \
    Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueType: expandsz; ValueName: "PATH"; ValueData: "{olddata};{app}"; \
    Check: NeedsAddPath('{app}')
Root: HKLM; \
    Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueName: "PATH"; ValueData: "{app}"; Flags: uninsdeletevalue
[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;

Taking a look to the code, it's possible to note the following instruction:

Root: HKLM; \
    Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueName: "PATH"; ValueData: "{app}"; Flags: uninsdeletevalue

I used that instruction, adapted (in my opinion) for the my example, reading Inno Setup. How to uninstall registry value?

The use of uninsdeletevalue should be delete the value when the program is uninstalled, and in fact, when I run the uninstaller, the entire PATH variable is deleted, but I need to restore the PATH environment variable to the previous installation value. I think it's possible reading its value before run the installer, but I don't have any idea to how use it in the uninstall phase.

Can someone help me with a code example?


Solution

  • You cannot have Inno Setup remember the value on installation and restore it, when uninstalling using [Registry] section entry only.

    While you can code it, it's not good approach anyway as the PATH likely changes after the installation and you will discard any such changes.


    You have to search the PATH for your path and remove the path only.

    const
      EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
    
    procedure RemovePath(Path: string);
    var
      Paths: string;
      P: Integer;
    begin
      if not RegQueryStringValue(HKLM, EnvironmentKey, 'Path', Paths) then
      begin
        Log('PATH not found');
      end
        else
      begin
        Log(Format('PATH is [%s]', [Paths]));
    
        P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';');
        if P = 0 then
        begin
          Log(Format('Path [%s] not found in PATH', [Path]));
        end
          else
        begin
          if P > 1 then P := P - 1;
          Delete(Paths, P, Length(Path) + 1);
          Log(Format('Path [%s] removed from PATH => [%s]', [Path, Paths]));
    
          if RegWriteStringValue(HKLM, EnvironmentKey, 'Path', Paths) then
          begin
            Log('PATH written');
          end
            else
          begin
            Log('Error writing PATH');
          end;
        end;
      end;
    end;
    
    procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
    begin
      if CurUninstallStep = usUninstall then
      begin
        RemovePath(ExpandConstant('{app}'));
      end;
    end;