Skip to content

Windows: Modify PATH without requiring a system restart? #1614

@DavisVaughan

Description

@DavisVaughan

Hi there, first off, great tool! Really appreciate the excellent work here!

I noticed that on Windows when you install ruff using the cargo-dist installer script, as of ruff 0.8.0 it often requires a restart of your whole machine the first time around to get the updates to the PATH in the registry to propagate. The reason this happens in 0.8.0 is due to the changes in ruff to use ~/.local/bin as the install location (the right choice, I think), which often doesn't exist yet on Windows and has to be created and added to the PATH by cargo-dist. Note that previously ruff used the default of cargo's bin/ directory, which often does already exist on the PATH from cargo itself if the user has installed Rust before, so this didn't show up as often before. astral-sh/ruff#14457

PS D:\Users\davis-vaughan> powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"                                 
Downloading ruff 0.8.0 (x86_64-pc-windows-msvc)                                                                         
Installing to D:\Users\davis-vaughan\.local\bin
  ruff.exe
everything's installed!

To add D:\Users\davis-vaughan\.local\bin to your PATH, either restart your system or run:

    set Path=D:\Users\davis-vaughan\.local\bin;%Path%   (cmd)
    $env:Path = "D:\Users\davis-vaughan\.local\bin;$env:Path"   (powershell)

From what I understand, modifying the PATH in the registry typically requires that you kill any processes and restart them to get them to have an updated copy of the PATH. It isn't enough to just kill cmd.exe though (i.e. a standard shell restart), as explorer.exe is the parent process of each Command Prompt so explorer.exe itself must be restarted. This is possible without rebooting the system but not elegantly, and it is easier to just tell people to reboot Windows.


However! I am fairly confident there is a way to "notify" all processes that they should refresh the environment. For example, the cargo installer does not require a system restart for you to get \.cargo\bin; on your PATH. The way they do this is by emitting a WB_SETTINGCHANGE event as described in this article:
https://web.archive.org/web/20091124062536/http://support.microsoft.com/kb/104011

You can even see the usage of it here:
https://github.com/search?q=org%3Arust-lang+WM_SETTINGCHANGE&type=code

I also noted that Inno Setup does this too:
https://github.com/jrsoftware/issrc/blob/72dd250bb1ca19bd1e6d3a48998722a4df059944/Projects/Src/Setup.InstFunc.pas#L1021

Which is why apps like rig (created with inno setup) don't require a system restart to get the path to rig to show up on the user's PATH, in inno setup you just set this https://github.com/r-lib/rig/blob/532d6e5d330a4b900cc26ff99be5559815b5a211/rig.iss#L32


So with all that in mind, I wonder if it is possible to fire this after a PATH update to get explorer.exe to refresh the environment, causing all subsequent cmd.exe to also have refreshed envs without a system restart - that would make for a much nicer first install experience.

  SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
    LPARAM(PChar('Environment')), SMTO_ABORTIFHUNG, 5000, @MsgResult);

CC @zanieb, as the author of that ruff PR I thought you may be interested in this

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions