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

前端 未结 3 1145
攒了一身酷
攒了一身酷 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 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;
    

提交回复
热议问题