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

Strange starting directory when launched from explorer.exe's address bar #12640

Closed
SainoNamkho opened this issue Mar 8, 2022 · 3 comments
Closed
Labels
Issue-Bug It either shouldn't be doing this or needs an investigation. Issue-Question For questions or discussion Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Resolution-Answered Related to questions that have been answered

Comments

@SainoNamkho
Copy link

SainoNamkho commented Mar 8, 2022

Windows Terminal version

1.4.201119003-release1.4

Windows build number

10.0.19042.685

Other Software

No response

Steps to reproduce

Config the starting directory of the default profile

{
            "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
            "commandline": "cmd.exe",
            "startingDirectory": "%__CD__%",

Run wt from the win+r diaglog:
image
Run wt from explorer.exe's address bar when cwd of explorer is something like %userprofile%\Downloads:
image
check the %__cd__% variable:

C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe>echo %cd%
C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe

C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe>echo %cd%\
C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\

C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe>echo %__cd__%
C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\

Config the starting directory of the default profile

{
            "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
            "commandline": "cmd.exe",
            "startingDirectory": "%CD%",

Run wt from the win+r diaglog:
image
Run wt from explorer.exe's address bar, still not same as cwd:
image

Config startingDirectory to %CD%\ or remove it from the profile:

the same as "%CD%".

Maybe related #7204 #12602

Expected Behavior

In some previous version which I cannot figure out, the terminal is launched the same path as the explorer.

Actual Behavior

I've not updated to the latest build because of a problem related to #6591, the .msixbundle file itself will cause a file system error,
but I can reproduce the problem on some other computers with new builds.


Additional problem:
The wt launched by explorer differs from that launched by win+r dialog not only in starting directory. There's also a special environment variable when launched from explorer.
Run !peb in WinDbg will get
image
This is the one launched from win+r
image
And the entry =::=::\ is added to explorer's environment after the terminal process is spawned.

@SainoNamkho SainoNamkho added the Issue-Bug It either shouldn't be doing this or needs an investigation. label Mar 8, 2022
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Mar 8, 2022
@SainoNamkho
Copy link
Author

SainoNamkho commented Mar 8, 2022

Correction:
"win+r dialog" mentioned above is actually taskmgr's "File - Run new task".
I assumed it to be same as win+r, but the win+r dialog behaves more like explorer.exe.

@zadjii-msft
Copy link
Member

https://ss64.com/nt/syntax-variables.html

Variable Dynamic (update every time used) Volatile (Set at Logon) Shell Variable User Environment Variable(SETX) System Environment Variable(SETX /M) Default value assuming the system drive is C:
CD Y   Y     The current directory (string).

....

Undocumented Dynamic variables (read only)

  • %__CD__% The current directory, terminated with a trailing backslash. (Global)

Other S/O post that may be helpful: https://stackoverflow.com/questions/20156490/why-cant-i-access-a-variable-named-cd-on-windows-7/20169219#20169219

Just from skimming those, I'm betting whatever weird logic the OS uses to figure out %__CD__% behaves differently for a packaged application like the Terminal. Maybe that's why you're always getting the package directory when launched from explorer.exe, and not from the Run dialog.


Consider the following test cases, from the explorer address bar:

  • conhost cmd.exe /k echo %cd%
  • cmd.exe /k echo %cd% (with defterm enabled, so this cmd.exe starts in the Terminal)
  • wt -d %cd%

You'll get the following windows:

image

  • The first started cmd.exe, which then evaluated %cd% as the CWD that cmd.exe was started in, which is D:\dev\public\terminal
  • Same thing happened for the second window, but now cmd is running in the Terminal instead of conhost.
  • This is the key example. Here, we didn't start cmd.exe, we started the Terminal directly. Terminal tried to evaluate its CD variable (which it would have inherited from explorer), but there was no CD variable to evaluate. On (some newer versions of the Terminal than 1.4), the Terminal will correctly report to the user that %CD% is a nonsensical path, and won't just silently fall back to %userprofile%.

Probably best to not rely on %CD% at all - I've a mind to change where wt.exe actually sets it's own CWD anyways, to somewhere that's not where the Terminal was actually started from (see #5506)

Reading between the lines though, you probably want to use . as the startingDirectory, not %CD%. I'm pretty sure %CD% is only actually set by cmd.exe itself, so if you try looking at explorer.exe, the variable isn't set there.

@eryksun is usually my go-to person for explaining the weird quirks of how environment variables are expanded. He can go ahead and correct whatever mistakes I've inevitably made explaining here.

@zadjii-msft zadjii-msft added Issue-Question For questions or discussion Resolution-Answered Related to questions that have been answered labels Mar 16, 2022
@eryksun
Copy link

eryksun commented Mar 16, 2022

Currently, __CD__, __APPDIR__, FIRMWARE_TYPE, and NUMBER_OF_PROCESSORS are dynamic variables provided by GetEnvironmentVariableW() and ExpandEnvironmentStringsW() and implemented by the NT runtime library function RtlQueryEnvironmentVariable(). If they're set as real variables via SetEnvironmentVariableW(), the value from the environment block is ignored by GetEnvironmentVariableW() and ExpandEnvironmentStringsW(). The latter isn't necessarily the case for language runtimes, particularly those that work from a copy of the process environment block (e.g. C _wenviron, _wgetenv(), etc).

When a process is spawned via CreateProcess[AsUser]W() , if lpCurrentDirectory is set, it must name an existing directory (off-topic note: long paths aren't supported), else the call fails with ERROR_DIRECTORY. Passing "%CD%" for lpCurrentDirectory is resolved as a literal filename relative to the current working directory of the spawning process (e.g. WindowsTerminal.exe). CD is a dynamic variable in the CMD shell, so it's only reasonable to use it in a command line that's evaluated by CMD, such as cmd.exe /k echo %cd%.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Bug It either shouldn't be doing this or needs an investigation. Issue-Question For questions or discussion Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Resolution-Answered Related to questions that have been answered
Projects
None yet
Development

No branches or pull requests

3 participants