Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Auto update environment variables from system on WM_SETTINGCHANGE like explorer.exe #468

Closed
strrchr opened this issue Dec 16, 2015 · 31 comments

Comments

@strrchr
Copy link

strrchr commented Dec 16, 2015

When I change PATH or some other system environment variables, open a new tab in ConEmu, I think ConEmu should use the new system environment variables.
For explorer.exe, I open a new console by "open prompt here", it does use the new system environment variables.

@Maximus5
Copy link
Owner

Explorer ignores, well it actually do not even support, change/apply variables for its process.

But when you run ConEmu...

  1. It inherits all variables of parent process. For example, you run terminal from WAMP, GitExtensions, something, and you have properly changes/configured environment. Well, what would you have, if ConEmu just "reloads" variables from system? All "proper" variables would dissapear.
  2. User may even export changes from console up to ConEmu process. You would lose these changes too.

So, I consider processing of this message would be harmful

@strrchr strrchr closed this as completed Dec 27, 2015
@Maximus5
Copy link
Owner

Hmm. Probably, ConEmu may ask user what they want to do, when WM_SETTINGCHANGE received.

@reider-roque
Copy link

I second this feature request.

ConEmu does not have to update all variables from the system. But for the PATH variable this functionality is a must.

Though because of the env variable export feature mentioned above (granted I understood its mechanism correctly) one will have to think carefully on how to make it right. To keep the internal changes to PATH variable intact you'll have to differentiate changes to the PATH variable introduced by the internal export feature from those introduced by the external changes to system and/or user PATH variables.

The idea I have in mind is a bit convoluted, but I'll try to explain it. When ConEmu starts you should save the original PATH variable that was inherited from the parent process to CONEMU_PATH.
Then with every change to the PATH variable by the internal export feature you'll have to see what was added/removed to the original PATH and save those deltas. You should also apply those new changes (deltas) to CONEMU_PATH and then SetEnvironmentVariable on it to introduce those changes to the process.
Next whenever WM_SETTINGCHANGE message arrives that CONEMU_PATH should be completely overwritten by changes made to user or/and system PATH variables. Then accumulated internal changes should be applied to it and again SetEnvironmentVariable should be used used to apply those changes to the process.

Here is the pseudo-code for what was described above:

// Somewhere when the ConEmu process starts
GetEnvironmentVariable("PATH", &CONEMU_PATH, CONEMU_PATH.Length)

PathChangeDeltas internalPathChangeDeltas = new PathChangeDeltas();

...
switch (Msg.message)
{
...
    case WM_SETTINGCHANGE:
        CONEMU_PATH = MACHINE_PATH + ";" + USER_PATH;
        CONEMU_PATH = ApplyDeltas(CONEMU_PATH, internalPathChangeDeltas);
        SetEnvironmentVariable("PATH", CONEMU_PATH);
        break;
    case WM_INTERNAL_PATH_EXPORT:
        String EXPORTED_PATH = Msg.wParam;
        newDeltas = getPathChangeDeltas(CONEMU_PATH, EXPORTED_PATH);
        CONEMU_PATH = ApplyDeltas(CONEMU_PATH, newDeltas);
        internalPathChangeDeltas.Append(newDeltas);
        SetEnvironmentVariable("PATH", CONEMU_PATH);
        break;
...
}

MACHINE_PATH and USER_PATH will have to be pulled from the respective branches of Windows registry.

The Append() method, should you choose to actually implement something similar to what I described, can destroy mutually cancelling deltas, e.g. if one delta adds "C:\Windows" to the path and another one removes it then both those deltas can be safely removed.

@Maximus5
Copy link
Owner

@reider-roque #468 (comment) note 1

@reider-roque
Copy link

@Maximus5, how does my suggestion of updating only the PATH variable contradict that note?

Also, I don't think that you will be able to easily change, if at all, Environment Variables of already started (in ConEmu) terminal processes (not sure what WAP and GitExtensions terminals are, I'm talking about things like cmd.exe, powershell.exe, or sh.exe started inside ConEmu). It is not the right thing to do anyway.

But timely update of the PATH variable of the ConEmu process so that all newly started terminals inherit the updated PATH shouldn't be a problem. At least that is the default behaviour I would expect of ConEmu.

@strrchr
Copy link
Author

strrchr commented Dec 30, 2015

I think explorer.exe update environment variables of itself from the following registry entries on WM_SETTINGCHANGE:

HKEY_CURRENT_USER\Environment
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

Then explorer.exe start a new process, the new process inherit the new environment variables.
ConEmu may provide an option to take this behavior.
For simplicity, we can ignore the exported changes from console up to ConEmu process.
Otherwise, there should be an algorithm to calculate the delta from ConEmu startup environment variables to system environemnt variables. And on WM_SETTINGCHANGE, load new system environemnt variables and apply the delta.

@reider-roque
Copy link

@strrchr you are correct about registry entries.

If you ignore the exported changes from console up to ConEmu process then, well, you will just break that exporting functionality. My suggestion, if implemented, would combine both features.

Though I already see that the algorithm I described above is not exactly correct. To calculate correct deltas you'll have to check for differences between PATH that was just exported up from terminal process and the original PATH the terminal process was started with. That is in ConEmu you'll have to store a per terminal process PATH snapshot (taken when that terminal process was started) for the purpose of calculating deltas.

On the side note, @Maximus5, consider the following case. You have two different terminals running in ConEmu. Let's say that ConEmu's PATH is "A;B;C". When two terminals were created they inherited that PATH. Now the first terminal makes changes to the PATH variable "A;B;C" -> "K;L;M". And it exports that path up to the ConEmu. Now ConEmu's PATH is "K;L;M". Then the second terminal changes its PATH "A;B;C" -> "X;Y;Z" and exports it up to ConEmu. Boom, you've just overwritten the "proper" PATH that was exported up by the first terminal with "proper" PATH that was exported up by the second terminal.

In the above case you allow one terminal to overwrite changes that were made by the other terminal, but at the same time you don't like the idea of overwriting ConEmu's environment by the system-wide environment changes, which, I argue, should at least take precedence to bottom-up environment updates.

@Maximus5
Copy link
Owner

PATH may be set not only by "export".
As I've said before, ConEmu may be used as a terminal for other products (WAMP (Open Server), MAME, build environments like Mozilla, and so on).
All of them set env.vars, and PATH is one of them.

So, PATH actually differs from system at the moment ConEmu starts.

However, we may save this startup delta too.

@Maximus5 Maximus5 reopened this Dec 30, 2015
@mehbos
Copy link

mehbos commented Feb 6, 2016

I use ConEmu as a replacement for cmd, so I want to be able to use my newly added or modified environment variables in new tabs of ConEmu, but it will totally ignore this changes for new tabs for reasons that you mentioned above.

Can't ConEmu just have an option for this(auto processing of WM_SETTINGCHANGED) or at least have a menu button or a command that reload all settings? This way new tabs may work with new settings and existing tabs can continue with old copy of variables.

@gcnm-pgeil
Copy link

+1

@zhaoguoyuan
Copy link

so...there are no way to refresh the environment variables of specific tab other than relogin?

@Maximus5
Copy link
Owner

@zhaoguoyuan Look, even if ConEmu would renew its environment (in roadmap actually) the application, running in ConEmu tab is running on their own responsibility. There is no proper way to "change" environment in some external process. For example, cygwin doesn't ever call Windows environment API functions.

@zhaoguoyuan
Copy link

@Maximus5 I think I understood what you said, I totally agree with that. Obviously there are no perfect on punch solution for all the problems, since "environment variables" is a big topic, especially when ConEmu interact with OS or other software in two ways, maybe we can list up the use cases and try to discuss them separately.

@sferencik
Copy link

+1 for this feature. I appreciate that ConEmu can do many wonderful things (export variables, host WAMP and what not) and one day maybe I'll learn to appreciate this too. But for the very simple (and probably the most common) use-case, when ConEmu acts as a multi-tab cmd.exe, it would be nice to minimise the surprise for the user.

As said by someone above:

  • if I start a new cmd.exe Window, I get a snapshot of the current system environment variables
  • in Console2, if I open a new tab, I get a snapshot too

Users come to ConEmu from these less fancy tools and have learned to get around with this not-very-fancy behaviour. Hardly anyone will be able to appreciate the fanciness as something positive...

@norswap
Copy link

norswap commented Jan 7, 2017

@Maximus5

The problem is that the behaviour is inconsistent when consoles are set up to open in new tabs.
(And I think this is what @sferencik is really trying to say.)

  • The first time I launch a console, ConEmu launches and inherits the explorer's environment.
  • The second time I launch it, assuming a ConEmu window is open, I get a new tab in that window, which inherits the ConEmu window's environment (so any intermediate changes to the explorer environment are not picked up).

In one case I inherit the explorer's environment, in the other I do not. Confusing, and bad.

If you set up ConEmu to open new windows instead of new tabs, you don't have that problem. Another inconsistency!

I don't really care about processing WM_SETTINGCHANGE or not. The environment of the ConEmu window doesn't preoccupy me*. It's the console I launched that really needs to inherit the explorer's environment

* Although I'm all in favor of #987 -- but at least the current behaviour has a certain logic to it.

@Koriit
Copy link

Koriit commented Jan 23, 2017

+1 for this feature
I would really love if I could on demand reload env variables in current tab and/or all tabs.

@omerigon
Copy link

omerigon commented Jul 6, 2017

@norswap is correct.
As a user the expected behavior is to get the latest env variable when we open a new console.
The fact that it is a new window or a new tab not is not relevant, behavior should be consistent.
In tabbed mode I need to close all consoles and the window to be able to get my updates and this an annoying behavior.

Any update on the request?

Olivier

@vaclavbartos
Copy link

+1 for this feature, at least as a menu option to manually reload environment. Sometimes it's a problem to restart whole ConEmu, e.g. due to long-running process in one of the tabs.

Fortunatelly, there's a workaround: Start the new shell (cmd.exe) from explorer and then use ConEmu's function "Attach to..." to move it into ConEmu.

@digeomel
Copy link

+1. Very annoying when you have multiple consoles open and have to close all.

@Maximus5
Copy link
Owner

Sort of workaround.
You may run cmd (or cmd -new_console:z if you use DefTerm) and export variables to ConEmu. Perhaps attach is required before export.
I believe, this may be automated via one shortcut on the Desktop.

@Ordiel
Copy link

Ordiel commented Nov 8, 2018

Call me crazy but its been 3 years, this is basic. Literally I only use Windows because my stupid company is bound to it but I swear never to code again supporting windows in whatever open source projects I contribute...

@Koriit
Copy link

Koriit commented Nov 8, 2018

Seems like chocolatey has already resolved this issue with a script:

https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd

I have been using it along with setx command and manual modifications and has been working like a charm so far.

The only "but" I have is that it only works in CMD, so if someone is using cygwin or some other shell derivative then you need to close it, "refresh" CMD and open again.

@norswap
Copy link

norswap commented Nov 8, 2018

The ability to run a script when opening a new tab would indeed be of tremendous help. I don't remember very well (it's been more than 18 months) but I tried to investigate that and I don't think it is possible in ConEmu. The ability to run a script whenever a console is opened (no matter the method) would also help. I someone wants to investigate...

@gregorko
Copy link

gregorko commented Nov 9, 2018

@norswap
It should be possible to run a script when opening a new tab. There is also a default script ConEmu adds to CMD tabs.
If you look into Settings -> Startup -> Tasks and click on one of the CMD tasks you should see its command in a text field. Usually it should start with cmd.exe. What you see after the /k option is a script that is run when the tab is opened. For example I use this:

cmd.exe /k "%ConEmuBaseDir%\CmdInit.cmd" -git C:\Development\Tools\ConEmuCmdInit.cmd''

%ConEmuBaseDir%\CmdInit.cmd is the ConEmu default script that does adjustments to the prompt and adds Git information if the -git option is specified. Followed by my own ConEmuCmdInit.cmd script that does initialization of my development environment.

@norswap
Copy link

norswap commented Nov 19, 2018

Indeed, I thought I had tested that already, but apparently not. I set my init script up to call a script that resets the PATH variable (one could use the ResetEnv.cmd script @Koriit linked above) and it works fine 👍

@adrian-baker
Copy link

In my first 5 minutes of using ConEmu, after several years of using several other terminals on Windows, I ran smack into this issue.

@Maximus5
Copy link
Owner

Maximus5 commented Apr 6, 2019

I really can't understand that. Do you change environment variables every 5 minutes on system level?

@adrian-baker
Copy link

adrian-baker commented Apr 6, 2019

>scoop install yarn
...
>yarn
bash: yarn: command not found

My first instinct was to open a new terminal, which didn't work. I then had to kill every terminal before it took effect, which I assumed was a bug.

@norswap
Copy link

norswap commented Apr 7, 2019

@Maximus5 No, but happens frequently that you have some consoles open, you need to install something (changes PATH), then you'd expect that opening a new console tab would have the new path (as it does when you open it from explorer). But nay. So now you either have to launch a new instance of ConEmu (but only if you didn't configure it to be single instance IIRC). Or remember the flag for launching a separate instance (no one does). Or (what people actually do) - clause all open consoles and relaunch.

Given how incredibly common that scenario is, and given how many options ConEmu already has, would it really be the end to fetch the new environment variable values from the register when launching a new console? Or potentially add the option to control this behaviour?

@inspiral
Copy link

Agree with feature requesters. As many people i also work on different solutions every week and have to install various tools, etc to try them out. Generally i have at least 5-6 consoles open with useful command histories. It really is an incovenience to restart cmder every time i install something because it doesn't have the refreshed PATH.

@Maximus5
Copy link
Owner

2019-05-27_02-00-25

When ConEmu receives the WM_SETTINGCHANGE with lParam=Environment it tries to load environment from registry, compare the data with previous try (from startup or WM_SETTINGCHANGE) and applies changes into it's own environment.
New variables will be available in the new consoles.
If one want to apply new variables to some active console, ConEmuC -GuiMacro EnvList prints actual NAME=VALUE pairs, you may parse them and apply into your shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests