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

前端 未结 3 1126
攒了一身酷
攒了一身酷 2020-12-16 07:08

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 w

相关标签:
3条回答
  • 2020-12-16 07:48

    These solutions for removing variable from PATH helped a lot, but for me there was a problem in Delete(Paths, P - 1, Length(Path) + 1); when path of my installer was at the beginning. Then Delete function will not work.

    My simple modification which worked for me was Delete(Paths, P, Length(Path) + 1);

    0 讨论(0)
  • 2020-12-16 07:57

    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(HKEY_LOCAL_MACHINE, 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(HKEY_LOCAL_MACHINE, 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;
    
    0 讨论(0)
  • 2020-12-16 08:11

    The problem seems to stick if a previous version was already installed, containing erroneous uninstall routines, and then updated with the new Setup. The Path was deleted no matter what, even if the Registry section had no Flags anymore. So my task was to write a new Setup that when updating faulty versions makes sure the Path is still there after uninstall.

    I came closest with Martin Prikryl's approach, but logging showed I need to save the Path at the beginning of the uninstall (usUninstall) and rewrite it at the end (usPostUninstall), else it wouldn't stick. Also, environment is already errorneous refreshed without Path when processing the usPostUninstall Step, so I added a manual environment refresh which I took from another post.

    Here's the final result that worked for me:

    var
      Paths: string;
    
    const
      EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
      SMTO_ABORTIFHUNG = 2;
      WM_WININICHANGE = $001A;
      WM_SETTINGCHANGE = WM_WININICHANGE;
    
    type
      WPARAM = UINT_PTR;
      LPARAM = INT_PTR;
      LRESULT = INT_PTR;
    
    function SendTextMessageTimeout(hWnd: HWND; Msg: UINT;
      wParam: WPARAM; lParam: PAnsiChar; fuFlags: UINT;
      uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
      external 'SendMessageTimeoutA@user32.dll stdcall';  
    
    procedure SaveOldPath();
    begin
      if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then
      begin
        Log('PATH not found');
      end else begin
        Log(Format('Old Path saved as [%s]', [Paths]));
      end;
    end;
    
    procedure RemovePath(Path: string);
    var
      P: Integer;
    begin
      Log(Format('Prepare to remove from Old PATH [%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
        Delete(Paths, P - 1, Length(Path) + 1);
        Log(Format('Path [%s] removed from PATH => [%s]', [Path, Paths]));
    
        if RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then
        begin
          Log('PATH written');
        end
          else
        begin
          Log('Error writing PATH');
        end;
      end;
    end;
    
    procedure RefreshEnvironment;
    var
      S: AnsiString;
      MsgResult: DWORD;
    begin
      S := 'Environment';
      SendTextMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
        PAnsiChar(S), SMTO_ABORTIFHUNG, 5000, MsgResult);
    end;
    
    procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
    begin
      if CurUninstallStep =  usUninstall then
      begin
        SaveOldPath();
      end;
      if CurUninstallStep = usPostUninstall then
      begin
        RemovePath(ExpandConstant('{app}'));
        RefreshEnvironment();
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题