microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
95.96k stars 8.35k forks source link

Targeting current instance with "-w 0" command line doesn't work if running as administrator #9628

Open DJackman123 opened 3 years ago

DJackman123 commented 3 years ago

Windows Terminal version (or Windows build number)

1.7.572.0

Other Software

No response

Steps to reproduce

Launch Windows Terminal as administrator Run the command line: wt -w 0 nt

Expected Behavior

This should open a new tab in the current window

Actual Behavior

Launches a new instance of Windows Terminal

It would make sense that I wouldn't be able to send commands to other WT windows that were running as admin, but running a command specifically targeting the current window should still work (as a special case if necessary).

zadjii-msft commented 3 years ago

Weird, because I definitely can't repro this locally. @miniksa Do you know if there's a way I could have @DJackman123 here collect the events emitted to a particular tracelogging GUID and send them to me? That is what all that logging is for after all

DHowett commented 3 years ago

Right, this is when you run wt -w 0 from an application hosted in the admin wt?

miniksa commented 3 years ago

Weird, because I definitely can't repro this locally. @miniksa Do you know if there's a way I could have @DJackman123 here collect the events emitted to a particular tracelogging GUID and send them to me? That is what all that logging is for after all

@zadjii-msft, you could ensure that the GUID you're thinking about is listed in src/ConsolePerf.wprp and then have @DJackman123 load that into Windows Performance Recorder with the Add Profiles... button in the bottom left, start the trace, repro the thing, then send you the recorded ETL file.

DHowett commented 3 years ago

I've got a version of that file laying around that has Terminal GUIDs in it... Just a sec :smile:

DHowett commented 3 years ago

Here is a version of the WPR profile that has all the Terminal GUIDs.

miniksa commented 3 years ago

Here is a version of the WPR profile that has all the Terminal GUIDs.

Dude. Put that in a PR and check that in.

DJackman123 commented 3 years ago

Playing around with this a bit more, I'm seeing this behavior:

  1. Start WT from the Start menu as administrator
  2. Run: wt -w 0 nt
  3. This opens a new instance of WT. It is also running elevated.
  4. In the new instance, run: wt -w 0 nt
  5. This does not open a new instance of WT, but correctly creates a new tab in the current instance (opened in step 3).

So it's not the fact that it's elevated that is causing the problem. It's something else around how it's launched from the Start menu? But when I launch WT non-elevated from the Start menu it works correctly in the first instance.

DHowett commented 3 years ago

huh. I don't love the implications that has on our activation stack.

Hey, are you getting a different config file when you run from the Run dialog?

DJackman123 commented 3 years ago

What specifically do you mean by "different config file"?

zadjii-msft commented 3 years ago

If you open the Settings file in both the first window that opens, and the second window (the one the subsequent wt -w 0 glommed to), are they the same file at the same path?

DJackman123 commented 3 years ago

Yes, it appears they are using the same settings file.

jdhitsolutions commented 3 years ago

I'm glad I finally found this issue. I see the same behavior on 1.8.1521.0 in Windows 10 21H1. Running wt -w 0 nt in a non-elevated Windows Terminal instance opens the new tab in the same instance. Doing the same thing in an elevated instance launches a new Windows Terminal instance, which is not what I want. The new instance is also elevated which is what I would expect.

DJackman123 commented 3 years ago

So it's not just me? I'm not going crazy?? If you run the wt -w 0 nt command in the new Windows Terminal instance that was started when you ran the command from the first elevated instance, what happens? For me I get a new tab in the second instance. So it works, but just not in the initial elevated instance.

jdhitsolutions commented 3 years ago

I concur. In my existing, elevated, Windows Terminal instance, when I run wt -w 0 I get a new instance of Windows Terminal, launching my default profile. IN THAT instance, every time I run wt -w 0 nt, it opens a new tab IN THE SAME instance. AND, the new tabs in the second instance are all running elevated. Which I would expect. But otherwise, this behavior makes no sense to me.

DJackman123 commented 3 years ago

It's been a few months. Any chance this one can get some love? Have you had a chance to look at the trace that I sent before?

..David..

hardeepparmar commented 3 years ago

@DJackman123 comment on other thread brought me here.. Yes i can confirm that if the first time terminal is launched with elevated privilege(i.,e Run As administrator) and you issue wt -w 0 nt it opens a new terminal window instance.. However if you again do the same from this new window..it opens(as expected) a tabbed window. However this works fine if you are either using command prompt window for issuing wt -w 0 nt command or if you are not running as administrator. I tried cmd /c wt -w 0 nt from with in PowerShell and even that does not work. I have tried with PW SHELL version 5.x and also 7.2.0-preview 9(latest as of date) and behavior is same. Also i opened PowerShell from with in command prompt tabbed window by typing pwsh OR vice versa (i.e by getting to cmd window from within powershell) and tried the same from there and even that does not work.
See below the first command opened a tabbed PowerShell window while the second one opened it in new instance. Should this be reported to PowerShell team? windows_terminal_run_as_admin_powershell_tabbed_window

zadjii-msft commented 2 years ago

Huh. Nothing is throwing any errors in this trace. Nothing is obviously wrong (other than the second window being established as the monarch).

Because that second process effectively sniped the Monarch registration, it's performed a coup. Now the first window thinks it's the king but every other window doesn't, so the first window is totally isolated. I'm gonna need to reach out to the COM folks on this one. I did not think that it was possible for one process to snipe the CoRegisterClassObject of another process.

zadjii-msft commented 2 years ago

idly: maybe the alias is pointing at a different version of the Terminal? Or like, a different exe? So the first one opens the ....

Nah that doesn't make sense. The Monarch is separated by "SKU", so Dev always talks to the same GUID, Preview always talks on a second GUID, and Release always on a third GUID, and those haven't changed. So if you did run Stable from the Start Menu, and wt.exe was pointing at Preview, then those windows would have wholly different settings. So that's not it.

Presumably, when you're in this state, running the "Identify Window" command gives "Window: 1" for both the windows. image image

zadjii-msft commented 2 years ago

Filed MSFT:39320463 to track. From the mail thread, this doesn't seem like our fault, but we should still figure it out.

AltitudeApps commented 2 years ago

Presumably, when you're in this state, running the "Identify Window" command gives "Window: 1" for both the windows.

Confirmed. Actually, I have 3 windows open. Two are elevated, and one is not. ALL THREE indicate "Window: 1" in response to the Identify Window command from the command palette.

I can confirm that the trick of running wt -w 0 nt again in the window that was launched (but shouldn't have launched) by a wt -w 0 nt command indeed does work, and it launches a new tab in this new window.

So, I guess the workaround will be to immediately issue a wt -w 0 nt command after launching an elevated wt.exe instance, and then close the first window. Things seem to work as expected after that.

Interestingly, I see that doing a wt -w 0 nt in EITHER of the elevated windows will result in a new tab appearing in the second window.

edit: I just reproduced this on a second machine.

zadjii-msft commented 1 year ago

Okay we got some heavy investigative help on this on. From the internal bug notes:

Flow is,

  1. User launches WindowsTerminal.exe as admin. Has Token A.
    1. WindowsTerminal.exe also launches an OOP COM server with Token A.
  2. Inside, OpenConsole.exe launches
  3. Inside, Powershell.exe launches, but .NET changes the token to add SeDebugPrivilege (for reasons). Token B!

So now user has a normal looking terminal, but the tokens are already in a weird state between window process and shell process.

User tries to open new tab with "wt.exe -w 0 nt" in terminal.

  1. wt.exe launches. With Token B (SeDebugPrivilege)!
    1. It then launches (the same) OOP COM. This should just fetch the existing instance from earlier, but,
  2. COM tries to find existing server
    1. Finds earlier instance
    2. Matches tokens Token A (first WindowsTerminal.exe instance) and Token B (new wt.exe instance).
    3. Tokens are different, so it makes a new OOP server. i.e. new window.

now, if you change your default shell from powershell.exe -> cmd.exe, then the bug goes away!

First. This doesn't repro on Desktop, but does on Centennial because there is an appmodel policy that changes COM's token matching function to be stricter for Centennial than Desktop, AppModelPolicy_ComTokenMatchingForAAAServers_UseNtCompareTokens.

Second. Supposedly the stricter token matching policy is only used because there is no classInfo (IComClassInfo) retrieved for your COM class.

    wil::com_ptr_nothrow<IComClassInfo> classInfo;
    RETURN_IF_FAILED(TryGetClassInfoForActivation(*pActParams, &classInfo));

because there's a bug in COM where they calculate the right thing for packages, but then clobber it by immediately recalculating that thing for Desktop. (I'm fuzzy on this part.)

There's an upstream bug, MSFT:39730477 that this was now duped to.

Major thanks to @jsidewhite and @brialmsft for digging in on the COM side of things