ofek / userpath

Cross-platform tool for adding locations to the user PATH, no elevated privileges required!
MIT License
151 stars 20 forks source link

Raise `WM_SETTINGCHANGE` after setting environment registry keys on Windows #40

Closed TBBle closed 2 years ago

TBBle commented 2 years ago

This is a feature request to resolve issues seen in https://github.com/pypa/pipx/issues/659, where after pipx ensurepath (implemented using this library), you must either log-out-and-in, or manually edit an env-var (both the env-var editor UI and setx appear to raise this message after applying their changes), before the PATH becomes active for new processes started from Explorer or other process-starting applications, e.g. ConEmu.

If WM_SETTINGCHANGE is raised after changing the registry key, then Windows Explorer (amongst others) will refresh its cache of the env-vars, and hence new cmd, powershell, etc. windows will see the new path immediately.

At some point Windows Terminal will also support handling this message, and so new tabs will see the updated PATH. ConEmu already supports this for new tabs, and Console2 is mentioned in a comment on that issue as supporting this. ConsoleZ also supports WM_SETTINGCHANGE, but that can be disabled.

That Windows Terminal issue link also has a bunch of discussion of the low-level details of the Explorer and application-specific behaviour when receiving the message, but they're not super-important here, as the sender-side is pretty close to:

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)TEXT("Environment"), SMTO_NORMAL, 1000, nullptr);

and poking around, there's some Python-implemented versions of this call at https://stackoverflow.com/q/21138014/166389.

ofek commented 2 years ago

Is the goal for updates to affect the current session, sort of like an automatic source ~/.bashrc?

TBBle commented 2 years ago

No, I don't think that's possible, unless the shell itself, e.g., cmd or PowerShell, also reacts to this message and refreshes its environment, which would require managing/merging any user-local changes to the values.

setx, for example, documents that it does not affect the current session. set in contrast is a built-in for CMD, and so can change the current session's environment (but does not persist the changes).

Ah, I see now that I left that detail out in the original request. Sorry, I've clarified that this is for new apps started from Explorer or other process-starting applications.

For example, ConEmu handles this message too so new tabs will see the PATH change, where right now I expect they do not if the user does not take some other action.

ofek commented 2 years ago

Should be supported in https://pypi.org/project/userpath/1.8.0/

TBBle commented 2 years ago

Awesome. Tested okay in the context of pipx: https://github.com/pypa/pipx/issues/659#issuecomment-1025271187