starting Terminal with wt no longer returns the main window handle of the resulting window #9867

Closed
opened 2026-01-31 02:05:59 +00:00 by claunia · 52 comments
Owner

Originally created by @torchgm on GitHub (Jul 27, 2020).

Environment

Windows build number: 10.0.20175.0
Windows Terminal version (if applicable): 1.2.2022

Any other software?
N/A

Steps to reproduce

Open Windows Terminal 1.2.2022 from code that supports returning the main window handle; for example in C# .NET

using System;
using System.Diagnostics;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Process p = Process.Start("wt"); // Start Windows Terminal
            Thread.Sleep(1000); // Wait a second to make sure it's open
            Console.WriteLine(p.MainWindowHandle.ToString()); // Print handle to console
            Console.ReadLine(); // Wait for user input before finishing
        }
    }
}

Expected behavior

The handle for the subsequently opened window is returned. In the example above, a numerical value representing the window handle is printed to the console (such as 856282)

Actual behavior

A handle of 0 is returned.

Originally created by @torchgm on GitHub (Jul 27, 2020). # Environment ```none Windows build number: 10.0.20175.0 Windows Terminal version (if applicable): 1.2.2022 Any other software? N/A ``` # Steps to reproduce Open Windows Terminal 1.2.2022 from code that supports returning the main window handle; for example in C# .NET ```csharp using System; using System.Diagnostics; using System.Threading; namespace Test { class Program { static void Main(string[] args) { Process p = Process.Start("wt"); // Start Windows Terminal Thread.Sleep(1000); // Wait a second to make sure it's open Console.WriteLine(p.MainWindowHandle.ToString()); // Print handle to console Console.ReadLine(); // Wait for user input before finishing } } } ``` # Expected behavior The handle for the subsequently opened window is returned. In the example above, a numerical value representing the window handle is printed to the console (such as `856282`) # Actual behavior A handle of `0` is returned.
claunia added the Resolution-By-DesignNeeds-TriageNeeds-Tag-FixNeeds-Attention labels 2026-01-31 02:05:59 +00:00
Author
Owner

@torchgm commented on GitHub (Jul 27, 2020):

Alrighty, just discovered the reason for this being #6860, and fair enough it's not an API, although would it be possible to also reinstate a direct app execution alias as WindowsTerminal (or wtalias, or something like that)? It would be very-much appreciated.

@torchgm commented on GitHub (Jul 27, 2020): Alrighty, just discovered the reason for this being #6860, and fair enough it's not an API, although would it be possible to also reinstate a direct app execution alias as `WindowsTerminal` (or `wtalias`, or something like that)? It would be very-much appreciated.
Author
Owner

@DHowett commented on GitHub (Jul 27, 2020):

What is your use case?

@DHowett commented on GitHub (Jul 27, 2020): What is your use case?
Author
Owner

@torchgm commented on GitHub (Jul 27, 2020):

Probably rather petty, but it was the only reliable way to alter its parent without user interaction and as such be able to do stuff such as use it as a desktop wallpaper:
terminal-wallpaper

It's probably possible to just start the process and then iterate through every window until I find something with the correct title but that feels super-messy and isn't very reliable.

@torchgm commented on GitHub (Jul 27, 2020): Probably rather petty, but it *was* the only reliable way to alter its parent without user interaction and as such be able to do stuff such as use it as a desktop wallpaper: ![terminal-wallpaper](https://user-images.githubusercontent.com/31840547/88499452-c63ee280-cfbd-11ea-8db9-74298ebcc4a0.png) It's probably possible to just start the process and then iterate through every window until I find something with the correct title but that feels super-messy and isn't very reliable.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Jul 27, 2020):

Could reparenting instead be implemented as a command-line option similar to xterm -into windowId? Related to https://github.com/microsoft/terminal/issues/4572.

@KalleOlaviNiemitalo commented on GitHub (Jul 27, 2020): Could reparenting instead be implemented as a command-line option similar to [**xterm -into** _windowId_](https://linux.die.net/man/1/xterm)? Related to <https://github.com/microsoft/terminal/issues/4572>.
Author
Owner

@zadjii-msft commented on GitHub (Jul 27, 2020):

I'm just gonna put this out there, with the process model changes coming in #5000, I'm fully expecting this (officially unsupported) scenario to break further.

@zadjii-msft commented on GitHub (Jul 27, 2020): I'm just gonna put this out there, with the process model changes coming in #5000, I'm fully expecting this (officially unsupported) scenario to break further.
Author
Owner

@torchgm commented on GitHub (Jul 27, 2020):

I'm well-aware this isn't supported officially in any capacity, although this same ability to set an app as a wallpaper works pretty consistently across even more complex apps; I'm not expecting it to be perfect nor would I ever ask for any changes that would solely benefit such a scenario, although it would be really nice to have a traditional alias available as well as the shim. I do however entirely understand if this isn't feasible and'll happily respect that.

@torchgm commented on GitHub (Jul 27, 2020): I'm well-aware this isn't supported officially in any capacity, although this same ability to set an app as a wallpaper works pretty consistently across even more complex apps; I'm not expecting it to be perfect nor would I ever ask for any changes that would solely benefit such a scenario, although it would be really nice to have a traditional alias available as well as the shim. I do however entirely understand if this isn't feasible and'll happily respect that.
Author
Owner

@DHowett commented on GitHub (Jul 27, 2020):

So, okay, this is really cool and I'm sorry we broke it. We've got some changes in store that are probably going to make this worse before it makes it better. Once #5000 lands, even WindowsTerminal.exe isn't really going to have an HWND to hand out...

@zadjii-msft: gvim supports a --windowid parameter that allows for hosting. 1-10 how mad would it be if we ... did something that .. was horrible like that?

image

@DHowett commented on GitHub (Jul 27, 2020): So, okay, this is **really cool** and I'm sorry we broke it. We've got some changes in store that are probably going to make this _worse_ before it makes it better. Once #5000 lands, even WindowsTerminal.exe isn't really going to have an HWND to hand out... @zadjii-msft: gvim supports a `--windowid` parameter that allows for hosting. 1-10 how mad would it be if we ... did something that .. was horrible like that? ![image](https://user-images.githubusercontent.com/189190/88597255-b655eb80-d01b-11ea-8b1f-eda7867d4929.png)
Author
Owner

@torchgm commented on GitHub (Jul 28, 2020):

I mean something like that would be perfect! I just tried it out in vim and now I have it stuck as my wallpaper so that's fun. And no worries about breaking anything, it's to be expected! Terminal is still super-awesome anyway and I'd hate to have silly little things like this hold it back; I can't wait to see the changes you have planned come to fruition.

@torchgm commented on GitHub (Jul 28, 2020): I mean something like that would be perfect! I just tried it out in vim and now I have it stuck as my wallpaper so that's fun. And no worries about breaking anything, it's to be expected! Terminal is still super-awesome anyway and I'd hate to have silly little things like this hold it back; I can't wait to see the changes you have planned come to fruition.
Author
Owner

@DHowett commented on GitHub (Jul 28, 2020):

If I can suggest a somewhat obnoxious workaround for now: launching WT with --title [something you will recognize] and enumerating looking for that title might work acceptably. It's not excellent, but it is passable.

@DHowett commented on GitHub (Jul 28, 2020): If I can suggest a somewhat obnoxious workaround for now: launching WT with `--title [something you will recognize]` and enumerating looking for that title might work acceptably. It's not excellent, but it _is_ passable.
Author
Owner

@torchgm commented on GitHub (Jul 28, 2020):

I'll probably end up doing that for now, thank you!

@torchgm commented on GitHub (Jul 28, 2020): I'll probably end up doing that for now, thank you!
Author
Owner

@zadjii-msft commented on GitHub (Jul 28, 2020):

@DHowett what the heck am I even looking at there 🙃

is gvim just, hijacking the notepad HWND? How?

I'm not sure that this would be helpful for our window/content process idea, but could be neat for embedding the window in something else (as insane as that is)

@zadjii-msft commented on GitHub (Jul 28, 2020): @DHowett what the heck am I even looking at there 🙃 is gvim just, hijacking the notepad HWND? How? I'm not sure that this would be helpful for our window/content process idea, but could be neat for embedding the window in something else (as insane as that is)
Author
Owner

@DHowett commented on GitHub (Jul 28, 2020):

So, little secret here on Windows: your application window can point to a random HWND and say "yup, that's my parent!". Here, Notepad's main window is gvim's parent. I'm imagining more like, yeah, the Terminal could be embedded and literally host its entire UI in somebody else's window. It's largely orthogonal to our multi-process/content process work, and it could be related to (or the underpinnings of) "quake" mode.

@DHowett commented on GitHub (Jul 28, 2020): So, little secret here on Windows: your application window can point to a random HWND and say "yup, that's my parent!". Here, Notepad's main window is gvim's parent. I'm imagining more like, yeah, the Terminal could be embedded and literally host its entire UI in somebody else's window. It's largely orthogonal to our multi-process/content process work, and it could be related to (or the underpinnings of) "quake" mode.
Author
Owner

@DHowett commented on GitHub (Aug 13, 2020):

Alright, I'm going to close this one out for now. I'd like to make sure we think about it in #5000, but there's a couple workarounds for the moment. 😄 Sorry about that.

If folks re-raise this issue once preview migrates to stable, we can reopen and redirect.

@DHowett commented on GitHub (Aug 13, 2020): Alright, I'm going to close this one out for now. I'd like to make sure we think about it in #5000, but there's a couple workarounds for the moment. :smile: Sorry about that. If folks re-raise this issue once preview migrates to stable, we can reopen and redirect.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@zadjii-msft @DHowett @torchgm I am looking for the same thing, but after reading this issue that has been closed, I am not sure what is the proper way to go about detecting the window id for reparenting it. I did a quick test in PowerShell using Start-Process, and while I can grab MainWindowHandle on pwsh.exe, the same property is empty for wt.exe:

PS C:\Users\mamoreau> $pwsh_proc = Start-Process -PassThru -FilePath pwsh.exe
PS C:\Users\mamoreau> $pwsh_proc.MainWindowHandle
986958
PS C:\Users\mamoreau> $wt_proc = Start-Process -PassThru -FilePath wt.exe
PS C:\Users\mamoreau> $wt_proc.MainWindowHandle
PS C:\Users\mamoreau>

This should be equivalent to the technique used in the C# sample code of this ticket. I am running Windows Terminal 1.5.10271.0 and the ticket speaks of a regression that was first observed in 1.2.2022. Is this fixed upstream but not released yet, or is there a different method of detection offered to find the window id for reparenting? It's not clear to me if it's been fixed, or if it is going to be fixed, how, and when.

@awakecoding commented on GitHub (Feb 8, 2021): @zadjii-msft @DHowett @torchgm I am looking for the same thing, but after reading this issue that has been closed, I am not sure what is the proper way to go about detecting the window id for reparenting it. I did a quick test in PowerShell using Start-Process, and while I can grab MainWindowHandle on pwsh.exe, the same property is empty for wt.exe: ``` PS C:\Users\mamoreau> $pwsh_proc = Start-Process -PassThru -FilePath pwsh.exe PS C:\Users\mamoreau> $pwsh_proc.MainWindowHandle 986958 PS C:\Users\mamoreau> $wt_proc = Start-Process -PassThru -FilePath wt.exe PS C:\Users\mamoreau> $wt_proc.MainWindowHandle PS C:\Users\mamoreau> ``` This should be equivalent to the technique used in the C# sample code of this ticket. I am running Windows Terminal 1.5.10271.0 and the ticket speaks of a regression that was first observed in 1.2.2022. Is this fixed upstream but not released yet, or is there a different method of detection offered to find the window id for reparenting? It's not clear to me if it's been fixed, or if it is going to be fixed, how, and when.
Author
Owner

@zadjii-msft commented on GitHub (Feb 8, 2021):

Ah, to clarify - this was broken in ~v1.2, and we're about to break this even more before we fix it any time soon.

Reparenting the window isn't a currently supported scenario, so any workarounds we give you is certain to break again in the (near) future. I suppose we can use this thread for a discussion of how we might offer that in the future? I suppose it might help to have more details about what exactly you're trying to accomplish here. There's probably a difference between "we just want a single pane embedded in another HWND" vs "We want a straight up whole Windows Terminal instance in another HWND".

@zadjii-msft commented on GitHub (Feb 8, 2021): Ah, to clarify - this was broken in ~v1.2, and we're about to break this even more before we fix it any time soon. Reparenting the window isn't a currently supported scenario, so any workarounds we give you is certain to break again in the (near) future. I suppose we can use this thread for a discussion of how we might offer that in the future? I suppose it might help to have more details about what _exactly_ you're trying to accomplish here. There's probably a difference between "we just want a single pane embedded in another HWND" vs "We want a straight up whole Windows Terminal instance in another HWND".
Author
Owner

@torchgm commented on GitHub (Feb 8, 2021):

Personally for my use-case I'd prefer the ability to acquire the handle of then reparent the entire WT window, as this is a bit more versatile and means I can avoid making any particularly complex changes just to support it.

@torchgm commented on GitHub (Feb 8, 2021): Personally for my use-case I'd prefer the ability to acquire the handle of then reparent the entire WT window, as this is a bit more versatile and means I can avoid making any particularly complex changes just to support it.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@zadjii-msft ok, in this case it means it's worth creating an official feature request for Windows Terminal reparenting/embedding into a parent window. This is useful to implement an "embedded mode" for a product like Remote Desktop Manager where the user doesn't want multiple separate windows, but multiple tabs inside the same program. For instance, you may have a few tabs with RDP connections alongside a few terminal tabs. System administrators have a lot of diverse connection types, and those that can be hosted inside Windows Terminal are just a small fraction of them.

Here is a screenshot showing powershell.exe reparented inside Remote Desktop Manager. We launch powershell.exe, then wait until we can grab Process.MainWindowHandle and reparent it inside our own tab. It works well, the only downside is the powershell.exe terminal will briefly appear separately in between the time it has been created and the time it has been reparented. A better way would be to pass a command-line parameter with the parent window id, which is not possible AFAIK with most programs, but it doesn't mean we couldn't try doing it for Windows Terminal.

image

@awakecoding commented on GitHub (Feb 8, 2021): @zadjii-msft ok, in this case it means it's worth creating an official feature request for Windows Terminal reparenting/embedding into a parent window. This is useful to implement an "embedded mode" for a product like Remote Desktop Manager where the user doesn't want multiple separate windows, but multiple tabs inside the same program. For instance, you may have a few tabs with RDP connections alongside a few terminal tabs. System administrators have a lot of diverse connection types, and those that can be hosted inside Windows Terminal are just a small fraction of them. Here is a screenshot showing powershell.exe reparented inside Remote Desktop Manager. We launch powershell.exe, then wait until we can grab Process.MainWindowHandle and reparent it inside our own tab. It works well, the only downside is the powershell.exe terminal will briefly appear separately in between the time it has been created and the time it has been reparented. A better way would be to pass a command-line parameter with the parent window id, which is not possible AFAIK with most programs, but it doesn't mean we couldn't try doing it for Windows Terminal. ![image](https://user-images.githubusercontent.com/295841/107264585-21dc3500-6a11-11eb-9c37-3a3bd535725f.png)
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@torchgm @zadjii-msft I installed Windows Terminal 1.1, an older version that still had a working Process.MainWindowHandle and I was able to reparent it inside Remote Desktop Manager. I circled it in red so you can see it, but our own tab control hides most of the Windows Terminal tab control, we can see a little bit of it, and I was able to create new Windows Terminal tabs, or trigger the dropdown selector for a new tab.

For this type of integration, the simplest would be to restore Process.MainWindowHandle + add a wt.exe command-line parameter to disable the Windows Terminal tab control, and effectively force it into a "single window mode" where tabs are disabled. Rather than use the Windows Terminal tabs, we would use our own tabs in Remote Desktop Manager and launch multiple instances of Windows Terminal instead, one per tab.

One may wonder why it would still be interesting to use Windows Terminal without its tabs: well, it does a whole lot more than tabs, it has better clipboard integration and is vastly more customizable than the old PowerShell terminal or command prompt.

image

@awakecoding commented on GitHub (Feb 8, 2021): @torchgm @zadjii-msft I installed Windows Terminal 1.1, an older version that still had a working Process.MainWindowHandle and I was able to reparent it inside Remote Desktop Manager. I circled it in red so you can see it, but our own tab control hides most of the Windows Terminal tab control, we can see a little bit of it, and I was able to create new Windows Terminal tabs, or trigger the dropdown selector for a new tab. For this type of integration, the simplest would be to restore Process.MainWindowHandle + add a wt.exe command-line parameter to disable the Windows Terminal tab control, and effectively force it into a "single window mode" where tabs are disabled. Rather than use the Windows Terminal tabs, we would use our own tabs in Remote Desktop Manager and launch multiple instances of Windows Terminal instead, one per tab. One may wonder why it would still be interesting to use Windows Terminal without its tabs: well, it does a whole lot more than tabs, it has better clipboard integration and is vastly more customizable than the old PowerShell terminal or command prompt. ![image](https://user-images.githubusercontent.com/295841/107266354-6537a300-6a13-11eb-9ecc-9c678038db3f.png)
Author
Owner

@DHowett commented on GitHub (Feb 8, 2021):

The configuration you're looking for is "alwaysShowTabs": false, "showTabsInTitlebar": false.

This window (in its default configuration) is not designed to be re-parented, and I'm not terribly interested in redesigning our application to serve such a narrow use case. I appreciate what you're trying to do here, but it's just not tenable that we should open the floodgates to an endless march of features so niche.

When we have content processes and swap chain panel hosting, perhaps the calculus here changes.

@DHowett commented on GitHub (Feb 8, 2021): The configuration you're looking for is `"alwaysShowTabs": false`, `"showTabsInTitlebar": false`. This window (in its default configuration) is not designed to be re-parented, and I'm not terribly interested in redesigning our application to serve such a narrow use case. I appreciate what you're trying to do here, but it's just not tenable that we should open the floodgates to an endless march of features so niche. When we have content processes and swap chain panel hosting, perhaps the calculus here changes.
Author
Owner

@zadjii-msft commented on GitHub (Feb 8, 2021):

I think the vastly better solution would be to have a re-usable "terminal" control that could be hosted by other applications, rather than trying to re-host our entire application in another HWND. If only we had considered this scenario as a part of the design of the Terminal 😜.

@awakecoding What UI framework are you using for Remote Desktop Connection? WPF? There might be a better solution here.

@zadjii-msft commented on GitHub (Feb 8, 2021): I think the vastly better solution would be to have a re-usable "terminal" control that could be hosted by other applications, rather than trying to re-host our entire application in another HWND. _If only we had considered this scenario as a part of the design of the Terminal_ 😜. @awakecoding What UI framework are you using for Remote Desktop Connection? WPF? There might be a better solution here.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Feb 8, 2021):

A better way would be to pass a command-line parameter with the parent window id

I wonder how hard it would be to add such a feature to conhost. That should bypass any UWP complications, at least.

@KalleOlaviNiemitalo commented on GitHub (Feb 8, 2021): > A better way would be to pass a command-line parameter with the parent window id I wonder how hard it would be to add such a feature to **conhost**. That should bypass any UWP complications, at least.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@DHowett don't be so quick to dismiss this feature request, it's more common and important than you might think. Windows Terminal is becoming the new default terminal on Windows, so instead of pushing ISVs to reimplement their clunky terminal control, you probably want them to reuse Windows Terminal as their go-to solution. I found out I am not the first to inquire about this. @RickStrahl @StefanKoell

This being said, simple window reparenting would be good enough for quick and dirty integration, and we'd be happy with it. The ideal solution is what @zadjii-msft suggested: a proper WPF control, which would be the logical equivalent of a WebView control for a browser, except we're embedding Windows Terminal and not a browser window. A WPF control would be an acceptable solution to us, and it would also be a better one in the long run because it is more flexible than a simple window reparenting.

@awakecoding commented on GitHub (Feb 8, 2021): @DHowett don't be so quick to dismiss this feature request, it's more common and important than you might think. Windows Terminal is becoming the new default terminal on Windows, so instead of pushing ISVs to reimplement their clunky terminal control, you probably want them to reuse Windows Terminal as their go-to solution. I found out I am not [the first to inquire about this](https://github.com/microsoft/terminal/issues/7084). @RickStrahl @StefanKoell This being said, simple window reparenting would be good enough for quick and dirty integration, and we'd be happy with it. The *ideal* solution is what @zadjii-msft suggested: a proper WPF control, which would be the logical equivalent of a WebView control for a browser, except we're embedding Windows Terminal and not a browser window. A WPF control would be an acceptable solution to us, and it would also be a better one in the long run because it is more flexible than a simple window reparenting.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@KalleOlaviNiemitalo I looked at how Windows Terminal handles its tabs in Process Explorer, and it appears to spawn one OpenConsole.exe subprocess with a bunch of command-line parameters to host each tab. Quick like that, I couldn't find a way to launch it in a way that would give me a usable Process.MainWindowHandle, but if this is what I think it is (just the tab without the Windows Terminal multi-tab management on top), then it might be a very interesting approach to hosting individual tabs inside a parent process. This is probably not exposed externally, but if it's possible to make a quick & dirty prototype with usable reparenting, I'd be willing to give it a shot.

@awakecoding commented on GitHub (Feb 8, 2021): @KalleOlaviNiemitalo I looked at how Windows Terminal handles its tabs in Process Explorer, and it appears to spawn one OpenConsole.exe subprocess with a bunch of command-line parameters to host each tab. Quick like that, I couldn't find a way to launch it in a way that would give me a usable Process.MainWindowHandle, but if this is what I think it is (just the tab without the Windows Terminal multi-tab management on top), then it might be a very interesting approach to hosting individual tabs inside a parent process. This is probably not exposed externally, but if it's possible to make a quick & dirty prototype with usable reparenting, I'd be willing to give it a shot.
Author
Owner

@DHowett commented on GitHub (Feb 8, 2021):

if this is what I think it is

It really isn't.

OpenConsole is a copy of C:\windows\system32\conhost.exe, the same console host that ships with Windows, built out of this repository. It's running in a mode where it outputs only text (control sequences) and consumes only text (also control sequences) and does not present any UI.

Everything relating to the act of being a terminal is entirely hosted within the WindowsTerminal.exe process.

@DHowett commented on GitHub (Feb 8, 2021): > if this is what I think it is It really isn't. OpenConsole is a copy of `C:\windows\system32\conhost.exe`, the same console host that ships with Windows, built out of this repository. It's running in a mode where it outputs only text (control sequences) and consumes only text (also control sequences) and does not present any UI. Everything relating to the act of _being a terminal_ is entirely hosted within the WindowsTerminal.exe process.
Author
Owner

@zadjii-msft commented on GitHub (Feb 8, 2021):

See, now I'm much more amenable to productizing the WPF control than I am to productizing "reparent the whole terminal". That's something that would need to get properly prioritized. The control already exists, but it's only for VS to consume right now - which gives us a lot of liberty in changing the interface at will.

We've always meant to productize both the WPF and UWP controls at some point. We've got some work planned for the next couple months that is certainly going to affect the API layer for them. Maybe once #5000 / #1256 is sorted out entirely, we can loop back around on this.

I'm re-purposing #6999 to track the work of productizing the controls. It's unfortunately not something we'll have time for in the 2.0 timeframe, but it's something we can certainly come back around on.

@zadjii-msft commented on GitHub (Feb 8, 2021): See, now I'm much more amenable to productizing the WPF control than I am to productizing "reparent the whole terminal". That's something that would need to get properly prioritized. The control already exists, but it's only for VS to consume right now - which gives us a lot of liberty in changing the interface at will. We've always _meant_ to productize both the WPF and UWP controls at some point. We've got some work planned for the next couple months that is certainly going to affect the API layer for them. Maybe once #5000 / #1256 is sorted out entirely, we can loop back around on this. I'm re-purposing #6999 to track the work of productizing the controls. It's unfortunately not something we'll have time for in the 2.0 timeframe, but it's something we can certainly come back around on.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

if this is what I think it is

It really isn't.

OpenConsole is a copy of C:\windows\system32\conhost.exe, the same console host that ships with Windows, built out of this repository. It's running in a mode where it outputs only text (control sequences) and consumes only text (also control sequences) and does not present any UI.

Everything relating to the act of being a terminal is entirely hosted within the WindowsTerminal.exe process.

Oh well, it was worth a shot then! No problem, the WPF approach looks like the best one anyway.

@awakecoding commented on GitHub (Feb 8, 2021): > > if this is what I think it is > > It really isn't. > > OpenConsole is a copy of `C:\windows\system32\conhost.exe`, the same console host that ships with Windows, built out of this repository. It's running in a mode where it outputs only text (control sequences) and consumes only text (also control sequences) and does not present any UI. > > Everything relating to the act of _being a terminal_ is entirely hosted within the WindowsTerminal.exe process. Oh well, it was worth a shot then! No problem, the WPF approach looks like the best one anyway.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@zadjii-msft @DHowett how much work would it take to restore Process.MainWindowHandle on the latest development builds? At a bare minimum, it may be usable for an intermediate integration where we'd just ship a copy of Windows Terminal and implement the embedded mode while waiting for the WPF control.

@awakecoding commented on GitHub (Feb 8, 2021): @zadjii-msft @DHowett how much work would it take to restore Process.MainWindowHandle on the latest development builds? At a bare minimum, it may be usable for an intermediate integration where we'd just ship a copy of Windows Terminal and implement the embedded mode while waiting for the WPF control.
Author
Owner

@DHowett commented on GitHub (Feb 8, 2021):

Restoring the window handle with our architecture is impossible. It's not something we removed, it's something that disappeared because we had to introduce a shim executable to make the rest of the app platform work.

If we remove that shim, a couple other things fail -- mainly, we would lose the ability to launch Terminal elevated with Ctrl+Shift+Enter from the Run dialog and PowerShell/cmd would go back to hanging when you run wt from them. There's more information in the commit that introduced the shim, 592c634577.

On the balance, with doing both simultaneously being impossible, I'd prefer elevation and powershell to work correctly.

@DHowett commented on GitHub (Feb 8, 2021): Restoring the window handle with our architecture is impossible. It's not something we _removed_, it's something that disappeared because we had to introduce a shim executable to make the rest of the app platform work. If we remove that shim, a couple other things fail -- mainly, we would lose the ability to launch Terminal elevated with Ctrl+Shift+Enter from the Run dialog and PowerShell/cmd would go back to hanging when you run `wt` from them. There's more information in the commit that introduced the shim, 592c63457781c9d753ae6648f03c96d998a0080e. On the balance, with doing both simultaneously being impossible, I'd prefer elevation and powershell to work correctly.
Author
Owner

@zadjii-msft commented on GitHub (Feb 8, 2021):

If we restore it for 1.7, there's a 99% chance I'm going to break it again in 1.8 😅.

Part of the trick here is that wt.exe is actually just launching windowsterminal.exe. App execution aliases are weird. Turns out the OS does not love having the app execution alias wt.exe point at a binary named windowsterminal.exe. So yea, wt just launches windowsterminal, which is why wt doesn't have a window handle. windowsterminal.exe does.

If you're just going to ship a copy of the entire Terminal in your application, you might as well just launch the windowsterminal.exe in the package instead of the execution alias wt.exe. (DISCLAIMER: I have no idea if that would work, and that suggestion is about as far as I'm willing to go for supporting that scenario)

@zadjii-msft commented on GitHub (Feb 8, 2021): If we restore it for 1.7, there's a 99% chance I'm going to break it again in 1.8 😅. Part of the trick here is that `wt.exe` is actually just launching `windowsterminal.exe`. App execution aliases are _weird_. Turns out the OS does not _love_ having the app execution alias `wt.exe` point at a binary named `windowsterminal.exe`. So yea, `wt` just launches `windowsterminal`, which is why `wt` doesn't have a window handle. `windowsterminal.exe` _does_. If you're just going to ship a copy of the entire Terminal in your application, you might as well just launch the `windowsterminal.exe` in the package instead of the execution alias `wt.exe`. (DISCLAIMER: I have no idea if that would work, and that suggestion is about as far as I'm willing to go for supporting that scenario)
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@zadjii-msft I just made it work using Windows Terminal 1.1, but now you're making me wonder if I can get it working with the very latest. I basically extracted an MSIX bundle and worked with the files directly. I modified settings.json to disable the tabs and it does exactly what I want, now if only I could control which settings.json files it would use to avoid polluting the global configuration, and if I could get a recent version of Windows Terminal, it would be perfect

image

@awakecoding commented on GitHub (Feb 8, 2021): @zadjii-msft I just made it work using Windows Terminal 1.1, but now you're making me wonder if I can get it working with the very latest. I basically extracted an MSIX bundle and worked with the files directly. I modified settings.json to disable the tabs and it does *exactly what I want*, now if only I could control which settings.json files it would use to avoid polluting the global configuration, and if I could get a recent version of Windows Terminal, it would be perfect ![image](https://user-images.githubusercontent.com/295841/107280308-2c54f980-6a26-11eb-941b-8613d56114d0.png)
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@zadjii-msft reparenting works if I launch WindowsTerminal.exe directly instead of wt.exe, even with the latest version! I extracted the files directly to do it, but all I would need to work around this problem is a trick to detect the full path to the real WindowsTerminal.exe and use it instead of wt.exe. That's something I can live with, I'd be surprised if I can't find a way to do that.

Now the only thing missing for me are ways to override the settings.json for the embedded mode only without affecting global configuration. Are there environment variables or command-line parameters to force using a special settings.json file? I need to override things like alwaysShowInTabs, showTabsInTitlebar, etc. Ideally all of it would be controlled from the parent program, independently from the configuration used by the external Windows Terminal. Does the working directory of WindowsTerminal.exe have any impact on this?

@awakecoding commented on GitHub (Feb 8, 2021): @zadjii-msft reparenting works if I launch WindowsTerminal.exe directly instead of wt.exe, even with the latest version! I extracted the files directly to do it, but all I would need to work around this problem is a trick to detect the full path to the real WindowsTerminal.exe and use it instead of wt.exe. That's something I can live with, I'd be surprised if I can't find a way to do that. Now the only thing missing for me are ways to override the settings.json for the embedded mode only without affecting global configuration. Are there environment variables or command-line parameters to force using a special settings.json file? I need to override things like alwaysShowInTabs, showTabsInTitlebar, etc. Ideally all of it would be controlled from the parent program, independently from the configuration used by the external Windows Terminal. Does the working directory of WindowsTerminal.exe have any impact on this?
Author
Owner

@torchgm commented on GitHub (Feb 8, 2021):

Running windowsterminal.exe if obtained from the Microsoft Store isn't possible unfortunately, it just throws an Access Denied error (as a normal user, as an administrator and from code as both). Assuming that the Store will be how Windows Terminal will be distributed primarily (nothing wrong with this, I quite appreciate the Store) then its unfortunately not a particularly viable solution 😢

@torchgm commented on GitHub (Feb 8, 2021): Running `windowsterminal.exe` if obtained from the Microsoft Store isn't possible unfortunately, it just throws an Access Denied error (as a normal user, as an administrator and from code as both). Assuming that the Store will be how Windows Terminal will be distributed primarily (nothing wrong with this, I quite appreciate the Store) then its unfortunately not a particularly viable solution 😢
Author
Owner

@DHowett commented on GitHub (Feb 8, 2021):

Access denied

this isn't unexpected. The directory Terminal lives in isn't intended to have its executables run directly (and this isn't a limitation we can overcome, sorry!)

@DHowett commented on GitHub (Feb 8, 2021): > Access denied this isn't unexpected. The directory Terminal lives in isn't intended to have its executables run directly (and this isn't a limitation we can overcome, sorry!)
Author
Owner

@torchgm commented on GitHub (Feb 8, 2021):

Oh no I'm totally aware of this being a limitation, just wanted to make sure it was clear for anyone else reading through this that it won't work for Store releases.

@torchgm commented on GitHub (Feb 8, 2021): Oh no I'm totally aware of this being a limitation, just wanted to make sure it was clear for anyone else reading through this that it won't work for Store releases.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@torchgm @DHowett @zadjii-msft yeah, I didn't know about this limitation. I found a way to detect the full path, but I hit the access denied error. It's a bummer, but a full copy of the files outside of the MSIX install location would still work.

PS > Join-Path $($(Get-AppxPackage -Name Microsoft.WindowsTerminal).InstallLocation) WindowsTerminal.exe
C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.5.10271.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe

Any hints about controlling the settings.json when launching WindowsTerminal.exe, assuming I've got a working copy that won't throw the access denied error?

@awakecoding commented on GitHub (Feb 8, 2021): @torchgm @DHowett @zadjii-msft yeah, I didn't know about this limitation. I found a way to detect the full path, but I hit the access denied error. It's a bummer, but a full copy of the files outside of the MSIX install location would still work. ``` PS > Join-Path $($(Get-AppxPackage -Name Microsoft.WindowsTerminal).InstallLocation) WindowsTerminal.exe C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.5.10271.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe ``` Any hints about controlling the settings.json when launching WindowsTerminal.exe, assuming I've got a working copy that won't throw the access denied error?
Author
Owner

@sylveon commented on GitHub (Feb 8, 2021):

Instead of trying to hack around the existing terminal app, why not copy the WPF control's source in your own code and consume that? This way it should work and you're not going to be broken by changes they make until stabilization.

@sylveon commented on GitHub (Feb 8, 2021): Instead of trying to hack around the existing terminal app, why not copy the WPF control's source in your own code and consume that? This way it should work and you're not going to be broken by changes they make until stabilization.
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

@sylveon I'm not so good with C# and WPF myself, but can you point me to the parts of the sources that have the WPF control? Is it actually fully usable today, just not officially documented and published?

@awakecoding commented on GitHub (Feb 8, 2021): @sylveon I'm not so good with C# and WPF myself, but can you point me to the parts of the sources that have the WPF control? Is it actually fully usable today, just not officially documented and published?
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

I know this looks like a dirty hack that will make most people in this thread cringe, but it's actually perfectly acceptable and would take very few code changes on our side to implement. I can detect Windows Terminal + copy the install location to a temporary directory to avoid the "access denied" error, see the end result:

image

Last item to check on my list is how to launch WindowsTerminal.exe and tell it where to read settings.json, such that I can feed it a modified configuration where all tabs are disabled.

@awakecoding commented on GitHub (Feb 8, 2021): I know this looks like a dirty hack that will make most people in this thread cringe, but it's actually perfectly acceptable and would take very few code changes on our side to implement. I can detect Windows Terminal + copy the install location to a temporary directory to avoid the "access denied" error, see the end result: ![image](https://user-images.githubusercontent.com/295841/107284100-41805700-6a2b-11eb-804e-52894d1b1aaa.png) Last item to check on my list is how to launch WindowsTerminal.exe and tell it where to read settings.json, such that I can feed it a modified configuration where all tabs are disabled.
Author
Owner

@sylveon commented on GitHub (Feb 8, 2021):

It's here: https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalControl

@sylveon commented on GitHub (Feb 8, 2021): It's here: https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalControl
Author
Owner

@awakecoding commented on GitHub (Feb 8, 2021):

I tried finding a way to force WindowsTerminal.exe to read settings.json from a given location, but it doesn't seem possible:
https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp

I did notice, however, that it uses a different path when inside the MSIX installation location as opposed to outside of it.

C:\Users\mamoreau\AppData\Local\Microsoft\Windows Terminal\settings.json
C:\Users\mamoreau\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json

Did I miss the way to tell where to load its settings? Being able to tell an application where to read its files is a common thing, and it definitely makes it much easier for testing with temporary settings that won't pollute the real ones.

@awakecoding commented on GitHub (Feb 8, 2021): I tried finding a way to force WindowsTerminal.exe to read settings.json from a given location, but it doesn't seem possible: https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp I did notice, however, that it uses a different path when inside the MSIX installation location as opposed to outside of it. C:\Users\mamoreau\AppData\Local\Microsoft\Windows Terminal\settings.json C:\Users\mamoreau\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json Did I miss the way to tell where to load its settings? Being able to tell an application where to read its files is a common thing, and it definitely makes it much easier for testing with temporary settings that won't pollute the real ones.
Author
Owner

@awakecoding commented on GitHub (Feb 9, 2021):

@sylveon @zadjii-msft how usable is the WPF control at this point? @StefanKoell reported not so long ago having tried it without much success, as it wasn't ready for prime-time yet. I know a WPF control is considered proper, but I would still very much like to do the simple window reparenting integration, because unlike the WPF control, it doesn't require shipping a full copy of Windows Terminal. I think both are complementary, not mutually exclusive.

Control over the settings.json file to embed Windows Terminal inside a parent application is an issue that would affect both window reparenting and the WPF control integration, but I couldn't find a corresponding feature request ticket for it. Even with a WPF control, it would be a whole lot better for the parent application to simply inject its own settings.json containing global configuration and preconfigured profiles. This would be the only way to handle storing profile configurations inside a password manager or any other type of application. It wouldn't make sense to overwrite the existing settings.json with temporary configuration, so the most straightforward approach would be to find a way to override the location of settings.json with a command-line parameter or an environment variable.

Is there such a feature request already? This is beneficial to both approaches to embedding Windows Terminal inside a parent application. From a quick look at the code, it only looks for settings.json inside two predetermined paths: one when inside an MSIX package, and one when "unpacked" or outside an MSIX package. It looks for LocalAppData with the following call, and I am not aware of a trick to force it to return something else (changing $Env:LocalAppData didn't work, but it was worth a shot):

SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_FORCE_APP_DATA_REDIRECTION, nullptr, &localAppDataFolder)

A simple environment variable to force WindowsTerminal.exe to use a given directory for its settings would be enough to solve this problem. All we'd need to do is generate the settings.json on-the-fly and tell WindowsTerminal.exe to use it.

@awakecoding commented on GitHub (Feb 9, 2021): @sylveon @zadjii-msft how usable is the WPF control at this point? @StefanKoell reported not so long ago having tried it without much success, as it wasn't ready for prime-time yet. I know a WPF control is considered proper, but I would still very much like to do the simple window reparenting integration, because unlike the WPF control, it doesn't require shipping a full copy of Windows Terminal. I think both are complementary, not mutually exclusive. Control over the settings.json file to embed Windows Terminal inside a parent application is an issue that would affect both window reparenting and the WPF control integration, but I couldn't find a corresponding feature request ticket for it. Even with a WPF control, it would be a whole lot better for the parent application to simply inject its own settings.json containing global configuration and preconfigured profiles. This would be the only way to handle storing profile configurations inside a password manager or any other type of application. It wouldn't make sense to overwrite the existing settings.json with temporary configuration, so the most straightforward approach would be to find a way to override the location of settings.json with a command-line parameter or an environment variable. Is there such a feature request already? This is beneficial to both approaches to embedding Windows Terminal inside a parent application. From a quick look at the code, it only looks for settings.json inside two predetermined paths: one when inside an MSIX package, and one when "unpacked" or outside an MSIX package. It looks for LocalAppData with the following call, and I am not aware of a trick to force it to return something else (changing $Env:LocalAppData didn't work, but it was worth a shot): `SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_FORCE_APP_DATA_REDIRECTION, nullptr, &localAppDataFolder)` A simple environment variable to force WindowsTerminal.exe to use a given directory for its settings would be enough to solve this problem. All we'd need to do is generate the settings.json on-the-fly and tell WindowsTerminal.exe to use it.
Author
Owner

@awakecoding commented on GitHub (Feb 9, 2021):

I found two related issues related to better control over the settings.json file location:

https://github.com/microsoft/terminal/issues/4566
https://github.com/microsoft/terminal/issues/2933

@oising any thoughts on this?

@awakecoding commented on GitHub (Feb 9, 2021): I found two related issues related to better control over the settings.json file location: https://github.com/microsoft/terminal/issues/4566 https://github.com/microsoft/terminal/issues/2933 @oising any thoughts on this?
Author
Owner

@sylveon commented on GitHub (Feb 9, 2021):

I don't know how usable it is as I don't write WPF

@sylveon commented on GitHub (Feb 9, 2021): I don't know how usable it is as I don't write WPF
Author
Owner

@StefanKoell commented on GitHub (Feb 15, 2021):

This weekend I tried to play around a bit and realized that the WpfControl I tried a couple of months ago wasn't the one which can now be found here:
https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalControl

So I cloned this repo and tried again with the new WpfTerminalControl which seems to work different as the one I used before. I seems to be a thin managed wrapper to the actual terminal. Maybe this approach is better than the one I tried.

Anyway, I wasn't really able to run the test project:
https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalTestNetCore

I was able to compile Windows Terminal using the PowerShell build scripts but I couldn't run the test app. I also wasn't able to find information on how it can be run. Are there any instructions out there?

@StefanKoell commented on GitHub (Feb 15, 2021): This weekend I tried to play around a bit and realized that the WpfControl I tried a couple of months ago wasn't the one which can now be found here: https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalControl So I cloned this repo and tried again with the new WpfTerminalControl which seems to work different as the one I used before. I seems to be a thin managed wrapper to the actual terminal. Maybe this approach is better than the one I tried. Anyway, I wasn't really able to run the test project: https://github.com/microsoft/terminal/tree/main/src/cascadia/WpfTerminalTestNetCore I was able to compile Windows Terminal using the PowerShell build scripts but I couldn't run the test app. I also wasn't able to find information on how it can be run. Are there any instructions out there?
Author
Owner

@awakecoding commented on GitHub (Nov 25, 2022):

@DHowett I'm working on my own Windows Terminal distribution (unpackaged MSIX in a nuget package), and launching WindowsTerminal.exe works with reparenting. Now I want to avoid *re-*parenting to simply provide the parent window handle to be used initially, but I'm having trouble figuring out how the primary window gets created through all the modern WinRT stuff.

I've used Spy++ to see what the window hierarchy looked like once reparented within RDM:
image

I've searched for code for calls to CreateWindow, but I'm having trouble finding which one is supposed to be the primary window used by Windows Terminal. Can you give me a hint as to what it would be called within the WT source code? Thanks!

EDIT: Of course, I had to find it right after asking question. Is it the "Island Window" in https://github.com/microsoft/terminal/blob/main/src/cascadia/WindowsTerminal/IslandWindow.cpp?

@awakecoding commented on GitHub (Nov 25, 2022): @DHowett I'm working on my own Windows Terminal distribution (unpackaged MSIX in a nuget package), and launching WindowsTerminal.exe works with reparenting. Now I want to avoid *re-*parenting to simply provide the parent window handle to be used initially, but I'm having trouble figuring out how the primary window gets created through all the modern WinRT stuff. I've used Spy++ to see what the window hierarchy looked like once reparented within RDM: ![image](https://user-images.githubusercontent.com/295841/204058732-a56304fc-0f08-405a-85d3-8e8b7840102a.png) I've searched for code for calls to CreateWindow, but I'm having trouble finding which one is supposed to be the primary window used by Windows Terminal. Can you give me a hint as to what it would be called within the WT source code? Thanks! EDIT: Of course, I had to find it right after asking question. Is it the "Island Window" in https://github.com/microsoft/terminal/blob/main/src/cascadia/WindowsTerminal/IslandWindow.cpp?
Author
Owner

@Joachim-Otahal commented on GitHub (Jun 16, 2025):

Subscribing since without MainWindowHandle I cannot get the metrics, cannot calculate the mouse position is someone clicks in a Terminals. Old-style CONHOST: Works.

@Joachim-Otahal commented on GitHub (Jun 16, 2025): Subscribing since without MainWindowHandle I cannot get the metrics, cannot calculate the mouse position is someone clicks in a Terminals. Old-style CONHOST: Works.
Author
Owner

@DHowett commented on GitHub (Jun 16, 2025):

"I am manually tracking the mouse position over the console window" is just about the scariest thing you could have said. Does mouse input mode (win32 or VT) not work properly for your use case? If it does, it also works over SSH (and more)... 🙂

@DHowett commented on GitHub (Jun 16, 2025): "I am manually tracking the mouse position over the console window" is just about the scariest thing you could have said. Does mouse input mode (win32 or VT) not work properly for your use case? If it does, it also works over SSH (and more)... 🙂
Author
Owner

@Joachim-Otahal commented on GitHub (Jun 16, 2025):

"I am manually tracking the mouse position over the console window" is just about the scariest thing you could have said. Does mouse input mode (win32 or VT) not work properly for your use case? If it does, it also works over SSH (and more)... 🙂

Apart from he weird sub-tone: If you have a suggestion how to get where your click with the mouse in text mode powershell+terminal, just spill it! If I have to go through some win32.dll with a bit glue, and you have a working solution, just say! I'm happy to try, and if it works I will thank you!

@Joachim-Otahal commented on GitHub (Jun 16, 2025): > "I am manually tracking the mouse position over the console window" is just about the scariest thing you could have said. Does mouse input mode (win32 or VT) not work properly for your use case? If it does, it also works over SSH (and more)... 🙂 Apart from he weird sub-tone: If you have a suggestion how to get where your click with the mouse in text mode powershell+terminal, just spill it! If I have to go through some win32.dll with a bit glue, and you have a working solution, just say! I'm happy to try, and if it works I will thank you!
Author
Owner

@DHowett commented on GitHub (Jun 16, 2025):

So, there are two main ways.

  • If your console application is already using VT (ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_VIRTUAL_TERMINAL_INPUT), you can request mouse reporting with VT sequences \e[?1002;1006h.
    • When the user interacts with the application window, you can read the position of their click on the input stream as another VT sequence. It's a dense document, but the list of control sequences goes into some depth about mouse reporting.
  • If you are using normal Windows APIs like SetConsoleMode and ReadConsoleInput, you can SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ... | ENABLE_MOUSE_INPUT) (make sure you add it to the existing mode)
    • When the user interacts with the app window, you can read MOUSE_EVENTs from ReadConsoleInput; they contain the buffer-relative coordinates and the specific mouse buttons that were held down/clicked/released. 🙂
@DHowett commented on GitHub (Jun 16, 2025): So, there are two main ways. - If your console application is already using VT (`ENABLE_VIRTUAL_TERMINAL_PROCESSING` and `ENABLE_VIRTUAL_TERMINAL_INPUT`), you can request mouse reporting with VT sequences `\e[?1002;1006h`. - When the user interacts with the application window, you can read the position of their click on the input stream as another VT sequence. It's a dense document, but [the list of control sequences](https://www.invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking) goes into some depth about mouse reporting. - If you are using normal Windows APIs like `SetConsoleMode` and `ReadConsoleInput`, you can `SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ... | ENABLE_MOUSE_INPUT)` (make sure you add it to the existing mode) - When the user interacts with the app window, you can read `MOUSE_EVENT`s from `ReadConsoleInput`; they contain the buffer-relative coordinates and the specific mouse buttons that were held down/clicked/released. 🙂
Author
Owner

@Joachim-Otahal commented on GitHub (Jun 16, 2025):

Thanks for the hint. I hope I can apply the second with powershell. The first, maybe if I am lucky...

@Joachim-Otahal commented on GitHub (Jun 16, 2025): Thanks for the hint. I hope I can apply the second with powershell. The first, maybe if I am lucky...
Author
Owner

@Joachim-Otahal commented on GitHub (Jun 27, 2025):

Just if someone searches for "powershell get MainWindowHandle for Windows Terminal", and/or "powershell get Window Position for Windows Terminal"... I have a free day today and this is what I came up to get the MainWindowHandle and Window position for both normal powershell and Windows Terminal.

# Get Window Position (Thanks "Scripting Guy")
Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class Window {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    }
    public struct RECT
    {
        public int Left;        // x position of upper-left corner
        public int Top;         // y position of upper-left corner
        public int Right;       // x position of lower-right corner
        public int Bottom;      // y position of lower-right corner
    }
"@

# Using $env:WT_SESSION is not reliable in some circumstances
# Therefore check parents. Twice up the tree for some environments needed.
$ProcessList = @(Get-CimInstance Win32_Process -Filter "ProcessId = $([System.Diagnostics.Process]::GetCurrentProcess().Id)")
$ProcessList += Get-CimInstance Win32_Process -Filter "ProcessId = $($ProcessList[-1].ParentProcessId)"
$ProcessList += Get-CimInstance Win32_Process -Filter "ProcessId = $($ProcessList[-1].ParentProcessId)"
$WindowsTerminal = $ProcessList.Where({$_.Path -like "*\WindowsTerminal.exe"})[0]

$MainWindowHandle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
if ([int]$MainWindowHandle -lt 1 -and $WindowsTerminal.ProcessId -gt 0) {
    Write-Verbose "Running inside Windows Terminal" -Verbose
    $MainWindowHandle = (Get-Process -PID $WindowsTerminal.ProcessId).MainWindowHandle
}

$MainWindowHandle

$WindowPosition = New-Object RECT
$Result = [Window]::GetWindowRect($MainWindowHandle,[ref]$WindowPosition)
$WindowPosition

@Joachim-Otahal commented on GitHub (Jun 27, 2025): Just if someone searches for "powershell get MainWindowHandle for Windows Terminal", and/or "powershell get Window Position for Windows Terminal"... I have a free day today and this is what I came up to get the MainWindowHandle and Window position for both normal powershell and Windows Terminal. ``` # Get Window Position (Thanks "Scripting Guy") Add-Type @" using System; using System.Runtime.InteropServices; public class Window { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); } public struct RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } "@ # Using $env:WT_SESSION is not reliable in some circumstances # Therefore check parents. Twice up the tree for some environments needed. $ProcessList = @(Get-CimInstance Win32_Process -Filter "ProcessId = $([System.Diagnostics.Process]::GetCurrentProcess().Id)") $ProcessList += Get-CimInstance Win32_Process -Filter "ProcessId = $($ProcessList[-1].ParentProcessId)" $ProcessList += Get-CimInstance Win32_Process -Filter "ProcessId = $($ProcessList[-1].ParentProcessId)" $WindowsTerminal = $ProcessList.Where({$_.Path -like "*\WindowsTerminal.exe"})[0] $MainWindowHandle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle if ([int]$MainWindowHandle -lt 1 -and $WindowsTerminal.ProcessId -gt 0) { Write-Verbose "Running inside Windows Terminal" -Verbose $MainWindowHandle = (Get-Process -PID $WindowsTerminal.ProcessId).MainWindowHandle } $MainWindowHandle $WindowPosition = New-Object RECT $Result = [Window]::GetWindowRect($MainWindowHandle,[ref]$WindowPosition) $WindowPosition ```
Author
Owner

@DHowett commented on GitHub (Jun 30, 2025):

Checking the parent process trivially fails when PowerShell is launched with the "Default Terminal Application" set to Windows Terminal.

This is difficult for a reason. The reason is that it should not be done.

YMMV. :)

@DHowett commented on GitHub (Jun 30, 2025): Checking the parent process trivially fails when PowerShell is launched with the "Default Terminal Application" set to Windows Terminal. This is difficult for a reason. The reason is that it should not be done. YMMV. :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#9867