Identify WindowsTerminal process ID #7868

Closed
opened 2026-01-31 01:14:34 +00:00 by claunia · 19 comments
Owner

Originally created by @jdhitsolutions on GitHub (May 1, 2020).

Description of the new feature/enhancement

I'd like a way to identify the process ID associated with a Windows Terminal session. In PowerShell, I can see the session and profile ID variables. And it is easy enough to run Get-Process and find the Windows Terminal process. But what if there are 2 instances running? How can I tell which ID goes with which?

Proposed technical implementation details (optional)

PowerShell has a built-in variable $pid that helps me identify the current PowerShell process. It would be nice to either create a variable like $wtpid. Or add another environment variable that identifies the process ID of this Windows Terminal instance.

Originally created by @jdhitsolutions on GitHub (May 1, 2020). # Description of the new feature/enhancement I'd like a way to identify the process ID associated with a Windows Terminal session. In PowerShell, I can see the session and profile ID variables. And it is easy enough to run Get-Process and find the Windows Terminal process. But what if there are 2 instances running? How can I tell which ID goes with which? # Proposed technical implementation details (optional) PowerShell has a built-in variable `$pid` that helps me identify the current PowerShell process. It would be nice to either create a variable like `$wtpid`. Or add another environment variable that identifies the process ID of *this* Windows Terminal instance.
claunia added the Issue-FeatureNeeds-Tag-FixResolution-Won't-Fix labels 2026-01-31 01:14:35 +00:00
Author
Owner

@DHowett-MSFT commented on GitHub (May 1, 2020):

Thanks for the request! I'm going to need a use case for this one o_O

@DHowett-MSFT commented on GitHub (May 1, 2020): Thanks for the request! I'm going to need a use case for this one o_O
Author
Owner

@DHowett-MSFT commented on GitHub (May 1, 2020):

(You can use (Get-Process -Id $PID).Parent to get at the WT hosting your powershell instance.)

@DHowett-MSFT commented on GitHub (May 1, 2020): (You can use `(Get-Process -Id $PID).Parent` to get at the WT hosting your powershell instance.)
Author
Owner

@jdhitsolutions commented on GitHub (May 1, 2020):

That PowerShell command only works in PowerShell 7, not Windows PowerShell. I am building a simple PowerShell tool that gets the Windows Terminal process and its children. This is not difficult if there is only one instance of Windows Terminal running. But I don't want to make that assumption.

@jdhitsolutions commented on GitHub (May 1, 2020): That PowerShell command only works in PowerShell 7, not Windows PowerShell. I am building a simple PowerShell tool that gets the Windows Terminal process and its children. This is not difficult if there is only one instance of Windows Terminal running. But I don't want to make that assumption.
Author
Owner

@jdhitsolutions commented on GitHub (May 1, 2020):

I have a viable workaround for my immediate need. Still, since you are already populating environment variables with profile_id and session, I'm hoping it isn't that hard to add wt_pid.

@jdhitsolutions commented on GitHub (May 1, 2020): I have a viable workaround for my immediate need. Still, since you are already populating environment variables with profile_id and session, I'm hoping it isn't that hard to add wt_pid.
Author
Owner

@oising commented on GitHub (May 2, 2020):

Hey Jeff -- for windows powershell, use (gwmi win32_process -Filter "processid = $pid").parentprocessid

PS C:\Users\oisin> gps -id (gwmi win32_process -Filter "processid = $pid").parentprocessid

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    675      37    55884      59052     307.84   6748   1 WindowsTerminal
@oising commented on GitHub (May 2, 2020): Hey Jeff -- for windows powershell, use `(gwmi win32_process -Filter "processid = $pid").parentprocessid` ``` PS C:\Users\oisin> gps -id (gwmi win32_process -Filter "processid = $pid").parentprocessid Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 675 37 55884 59052 307.84 6748 1 WindowsTerminal ```
Author
Owner

@jdhitsolutions commented on GitHub (May 3, 2020):

That's the workaround I'm using.

@jdhitsolutions commented on GitHub (May 3, 2020): That's the workaround I'm using.
Author
Owner

@oising commented on GitHub (May 3, 2020):

That's the workaround I'm using.

Ok, but how does that depend on the assumption that there's only one WT running? I'm not following.

@oising commented on GitHub (May 3, 2020): > That's the workaround I'm using. Ok, but how does that depend on the assumption that there's only one WT running? I'm not following.
Author
Owner

@jdhitsolutions commented on GitHub (May 3, 2020):

This workaround using WMI also solves the multiple instances issue. I originally started with a simple Get-Process WindowsTerminal to get the process ID and go from there. That's when I realized that wouldn't work with I had 2 instances running. AND I realized the Parent property was added in PS7. I should have taken a little more time to think things through before posting. Personally, I'm set with the use case I posted.

But I still think it would be handy to have a variable of some sort to indicate the process id just as we do with $pid in PowerShell.

@jdhitsolutions commented on GitHub (May 3, 2020): This workaround using WMI also solves the multiple instances issue. I originally started with a simple `Get-Process WindowsTerminal` to get the process ID and go from there. That's when I realized that wouldn't work with I had 2 instances running. AND I realized the Parent property was added in PS7. I should have taken a little more time to think things through before posting. Personally, I'm set with the use case I posted. But I still think it would be handy to have a variable of some sort to indicate the process id just as we do with $pid in PowerShell.
Author
Owner

@DHowett-MSFT commented on GitHub (May 11, 2020):

So, I've been hemming and hawing about this issue.

I don't want to introduce another environment variable exposing WT state for the following reasons:

  • Every environment variable we expose is an API we need to continue supporting
    • You might think that a PID is going to be stable, but if we make any process model changes (the likes of which might support "tab tearoff", or "mixed elevation" (!)), the previously inviolate assumption that a single WT process is the host of your shell breaks down
    • (We can't poke a new value for WT_PID into each process running under terminal if it changes live; that's incredibly invasive!)
  • Environment variables are, unfortunately, inherited . . . like, by code, and all the processes spawned in VSCode's integrated terminal.

I'm not sure the benefit here outweighs the cost, especially since there's a viable workaround 😄

@DHowett-MSFT commented on GitHub (May 11, 2020): So, I've been hemming and hawing about this issue. I don't want to introduce another environment variable exposing WT state for the following reasons: * Every environment variable we expose is an API we need to continue supporting * You might think that a PID is going to be stable, but if we make any process model changes (the likes of which might support "tab tearoff", or "mixed elevation" (!)), the previously inviolate assumption that a single WT process is the host of your shell breaks down * (We can't poke a new value for WT_PID into each process running under terminal if it changes live; that's incredibly invasive!) * Environment variables are, unfortunately, inherited . . . like, by `code`, and all the processes spawned in VSCode's integrated terminal. I'm not sure the benefit here outweighs the cost, especially since there's a viable workaround :smile:
Author
Owner

@tik9 commented on GitHub (Jun 20, 2021):

(gwmi win32_process -Filter "processid = $pid").parentprocessid
This workaround using WMI also solves the multiple instances issue. I originally started with a simple Get-Process WindowsTerminal to get the process ID and go from there. That's when I realized that wouldn't work with I had 2 instances running. AND I realized the Parent property was added in PS7. I should have taken a little more time to think things through before posting. Personally, I'm set with the use case I posted.

But I still think it would be handy to have a variable of some sort to indicate the process id just as we do with $pid in PowerShell.

In PS7, gwmi is deprecated and does not work. It is now get-ciminstance. I have several sub WindowsTerminal and one is freezing. So I want to get the freezing pid and stop it. In linux it would be ps axo pid,wchan:32,cmd taken here

@tik9 commented on GitHub (Jun 20, 2021): > (gwmi win32_process -Filter "processid = $pid").parentprocessid > This workaround using WMI also solves the multiple instances issue. I originally started with a simple `Get-Process WindowsTerminal` to get the process ID and go from there. That's when I realized that wouldn't work with I had 2 instances running. AND I realized the Parent property was added in PS7. I should have taken a little more time to think things through before posting. Personally, I'm set with the use case I posted. > > But I still think it would be handy to have a variable of some sort to indicate the process id just as we do with $pid in PowerShell. In PS7, `gwmi` is deprecated and does not work. It is now `get-ciminstance`. I have several sub WindowsTerminal and one is freezing. So I want to get the freezing pid and stop it. In linux it would be `ps axo pid,wchan:32,cmd` taken [here](https://askubuntu.com/questions/15437/why-is-my-terminal-freezing-up)
Author
Owner

@gerardog commented on GitHub (Sep 30, 2022):

Checking the parent process doesn't work if WT is the Default Terminal Application, and you launch a console app from a graphical UI app.

  • For example via Explorer, Win+R then pwsh (with WT as default terminal app) the process tree looks like.
svchost.exe -> WindowsTerminal.exe
svchost.exe -> OpenConsole.exe

explorer.exe -> pwsh.exe -> conhost.exe

The console window is actually hosted by WindowsTerminal.exe.

  • But if you launch WT.EXE, then a pwsh profile the process tree looks like this:
explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe
                                                                           |-> pwsh.exe

... and each additional PowerShell tab launches a new pair of OpenConsole.exe, pwsh.exe.

So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app.
But I found a terrible (but working) hack:

function Get-ConsoleHostProcessId {
  
    # Save Original ConsoleHost title	
    $oldTitle=$host.ui.RawUI.WindowTitle; 
    # Set unique console title.
    $r=(New-Guid); 
    $host.ui.RawUI.WindowTitle = "$r"; 
    #Find console window by title, then find console PID.
    $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID:*" -Raw
    
    if ($null -ne $result) {
        $consolePid = [int]($result.SubString(5).Trim());
    } else {
        $consolePid = 0;
    }        
    # Restore original ConsoleHost title.
    $host.ui.RawUI.WindowTitle=$oldTitle;

    return [int]$consolePid;
}
  
function Test-IsWindowsTerminal {
    $consolePid = Get-ConsoleHostProcessId;
    if ($consolePid -gt 0) {
        return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal";
    }
    return $false;
}
@gerardog commented on GitHub (Sep 30, 2022): Checking the parent process **doesn't work if WT is the Default Terminal Application**, and you launch a console app from a graphical UI app. - For example via Explorer, `Win+R` then `pwsh` (with WT as default terminal app) the process tree looks like. ``` svchost.exe -> WindowsTerminal.exe svchost.exe -> OpenConsole.exe explorer.exe -> pwsh.exe -> conhost.exe ``` The console window is actually hosted by `WindowsTerminal.exe`. - But if you launch `WT.EXE`, then a `pwsh` profile the process tree looks like this: ``` explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe |-> pwsh.exe ``` ... and each additional PowerShell tab launches a new pair of `OpenConsole.exe`, `pwsh.exe`. So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app. But I found a terrible (but working) hack: ``` powershell function Get-ConsoleHostProcessId { # Save Original ConsoleHost title $oldTitle=$host.ui.RawUI.WindowTitle; # Set unique console title. $r=(New-Guid); $host.ui.RawUI.WindowTitle = "$r"; #Find console window by title, then find console PID. $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:*" -Raw if ($null -ne $result) { $consolePid = [int]($result.SubString(5).Trim()); } else { $consolePid = 0; } # Restore original ConsoleHost title. $host.ui.RawUI.WindowTitle=$oldTitle; return [int]$consolePid; } function Test-IsWindowsTerminal { $consolePid = Get-ConsoleHostProcessId; if ($consolePid -gt 0) { return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal"; } return $false; } ```
Author
Owner

@german-one commented on GitHub (Oct 31, 2022):

@gerardog I've been struggling whether to publish my crazy attempt ... 🤣

Using Process Explorer I observed that the WindowsTerminal process has a handle to the Shell process open. Relying on the assumption that this is always the case I tried to write a piece of code that enumerates all open handles searching for the right process handle.
I'm fully aware that this is all based on assumptions, not recommended API, undocumented structures, unsafe memory handling, etc. Also, since I'm not experienced in PowerShell and C# I have no doubts that there is quite some room for improvements. However, I verified the results in Task Manager, Process Explorer, and Spy on Windows 11, ver. 10.0.22621.755. Turns out it works just fine for the current terminal process model.

Edit: I improved it a little ...

  • wrap unmanaged resources into managed objects to make the code more robust
  • use the ID of the Shell that actually spawned the Conhost process for investigations instead of relying on $PID
  • implement the Get-TermProc function that returns a System.Diagnostics.Process rather than only a process ID

Edit2:

  • make it PowerShell v.2 compliant

Last Edit:
You know what, I'm going to remove the PowerShell code here. I just created a repo with transcriptions in C, C++, and C# besides of the PowerShell script.
https://github.com/german-one/termproc


Output of the script, DefTerm vs. Conhost: DefTerm_vs_Conhost
@german-one commented on GitHub (Oct 31, 2022): @gerardog I've been struggling whether to publish my crazy attempt ... 🤣 Using Process Explorer I observed that the WindowsTerminal process has a handle to the Shell process open. Relying on the assumption that this is always the case I tried to write a piece of code that enumerates all open handles searching for the right process handle. I'm fully aware that this is all based on assumptions, not recommended API, undocumented structures, unsafe memory handling, etc. Also, since I'm not experienced in PowerShell and C# I have no doubts that there is quite some room for improvements. However, I verified the results in Task Manager, Process Explorer, and Spy on Windows 11, ver. 10.0.22621.755. Turns out it works just fine for the current terminal process model. Edit: I improved it a little ... - wrap unmanaged resources into managed objects to make the code more robust - use the ID of the Shell that actually spawned the Conhost process for investigations instead of relying on `$PID` - implement the `Get-TermProc` function that returns a `System.Diagnostics.Process` rather than only a process ID Edit2: - make it PowerShell v.2 compliant Last Edit: You know what, I'm going to remove the PowerShell code here. I just created a repo with transcriptions in C, C++, and C# besides of the PowerShell script. https://github.com/german-one/termproc <br> Output of the script, DefTerm vs. Conhost: <img width="269" alt="DefTerm_vs_Conhost" src="https://user-images.githubusercontent.com/46659645/200165836-2b6d806f-82f3-4ab4-9b9a-3b0a3a4c0d16.png">
Author
Owner

@BlueOnBLack commented on GitHub (Dec 3, 2022):

Test method using Sysinternals handle tool

https://pastebin.com/Q9EEMAkw

@BlueOnBLack commented on GitHub (Dec 3, 2022): Test method using Sysinternals handle tool https://pastebin.com/Q9EEMAkw
Author
Owner

@BlueOnBLack commented on GitHub (Dec 3, 2022):

Also leave here
Parent process Check demo
detect SUB SUB -> SUB -> WT.exe

https://pastebin.com/wiWqwK5Z

@BlueOnBLack commented on GitHub (Dec 3, 2022): Also leave here Parent process Check demo detect SUB SUB -> SUB -> WT.exe https://pastebin.com/wiWqwK5Z
Author
Owner

@BlueOnBLack commented on GitHub (Dec 3, 2022):

Also leave here - get PID of current seassion

https://pastebin.com/WYBwDca7

@BlueOnBLack commented on GitHub (Dec 3, 2022): Also leave here - get PID of current seassion https://pastebin.com/WYBwDca7
Author
Owner

@BlueOnBLack commented on GitHub (Dec 3, 2022):

some Explain ---
when wt is under 11 as default ...
WT keep handles of hidden process,
but it is never the parent proccess
so using handle tool to filter 'CMD(some_PID_HERE)' under any windowsterminal.exe files
so given the result, you find the pid :)
you can see what i'm talking about, open processEsxplorer or processHacker
search in handles section for process Type,
there is 2, one for cmd file under explorer.exe, and another one

@BlueOnBLack commented on GitHub (Dec 3, 2022): some Explain --- when wt is under 11 as default ... WT keep handles of hidden process, but it is never the parent proccess so using handle tool to filter 'CMD(some_PID_HERE)' under any windowsterminal.exe files so given the result, you find the pid :) you can see what i'm talking about, open processEsxplorer or processHacker search in handles section for process Type, there is 2, one for cmd file under explorer.exe, and another one
Author
Owner

@mrkey7 commented on GitHub (May 4, 2024):

Checking the parent process doesn't work if WT is the Default Terminal Application, and you launch a console app from a graphical UI app.

  • For example via Explorer, Win+R then pwsh (with WT as default terminal app) the process tree looks like.
svchost.exe -> WindowsTerminal.exe
svchost.exe -> OpenConsole.exe

explorer.exe -> pwsh.exe -> conhost.exe

The console window is actually hosted by WindowsTerminal.exe.

  • But if you launch WT.EXE, then a pwsh profile the process tree looks like this:
explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe
                                                                           |-> pwsh.exe

... and each additional PowerShell tab launches a new pair of OpenConsole.exe, pwsh.exe.

So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app. But I found a terrible (but working) hack:

function Get-ConsoleHostProcessId {
  
    # Save Original ConsoleHost title	
    $oldTitle=$host.ui.RawUI.WindowTitle; 
    # Set unique console title.
    $r=(New-Guid); 
    $host.ui.RawUI.WindowTitle = "$r"; 
    #Find console window by title, then find console PID.
    $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID:*" -Raw
    
    if ($null -ne $result) {
        $consolePid = [int]($result.SubString(5).Trim());
    } else {
        $consolePid = 0;
    }        
    # Restore original ConsoleHost title.
    $host.ui.RawUI.WindowTitle=$oldTitle;

    return [int]$consolePid;
}
  
function Test-IsWindowsTerminal {
    $consolePid = Get-ConsoleHostProcessId;
    if ($consolePid -gt 0) {
        return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal";
    }
    return $false;
}

Works in pwsh. error in powershell.

Select-String : A parameter cannot be found that matches parameter
name 'Raw'.
At C:\Users\Hill\Desktop\x.ps1:9 char:97
+ ...  LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID
:*" -Raw
+
    ~~~~
    + CategoryInfo          : InvalidArgument: (:) [Select-String]
   , ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.Pow
   erShell.Commands.SelectStringCommand
@mrkey7 commented on GitHub (May 4, 2024): > Checking the parent process **doesn't work if WT is the Default Terminal Application**, and you launch a console app from a graphical UI app. > > * For example via Explorer, `Win+R` then `pwsh` (with WT as default terminal app) the process tree looks like. > > ``` > svchost.exe -> WindowsTerminal.exe > svchost.exe -> OpenConsole.exe > > explorer.exe -> pwsh.exe -> conhost.exe > ``` > > The console window is actually hosted by `WindowsTerminal.exe`. > > * But if you launch `WT.EXE`, then a `pwsh` profile the process tree looks like this: > > ``` > explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe > |-> pwsh.exe > ``` > > ... and each additional PowerShell tab launches a new pair of `OpenConsole.exe`, `pwsh.exe`. > > So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app. But I found a terrible (but working) hack: > > ```powershell > function Get-ConsoleHostProcessId { > > # Save Original ConsoleHost title > $oldTitle=$host.ui.RawUI.WindowTitle; > # Set unique console title. > $r=(New-Guid); > $host.ui.RawUI.WindowTitle = "$r"; > #Find console window by title, then find console PID. > $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:*" -Raw > > if ($null -ne $result) { > $consolePid = [int]($result.SubString(5).Trim()); > } else { > $consolePid = 0; > } > # Restore original ConsoleHost title. > $host.ui.RawUI.WindowTitle=$oldTitle; > > return [int]$consolePid; > } > > function Test-IsWindowsTerminal { > $consolePid = Get-ConsoleHostProcessId; > if ($consolePid -gt 0) { > return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal"; > } > return $false; > } > ``` Works in pwsh. error in powershell. ``` Select-String : A parameter cannot be found that matches parameter name 'Raw'. At C:\Users\Hill\Desktop\x.ps1:9 char:97 + ... LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID :*" -Raw + ~~~~ + CategoryInfo : InvalidArgument: (:) [Select-String] , ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.Pow erShell.Commands.SelectStringCommand ```
Author
Owner

@MamiyaOtaru commented on GitHub (Nov 18, 2024):

Checking the parent process doesn't work if WT is the Default Terminal Application, and you launch a console app from a graphical UI app.

  • For example via Explorer, Win+R then pwsh (with WT as default terminal app) the process tree looks like.
svchost.exe -> WindowsTerminal.exe
svchost.exe -> OpenConsole.exe

explorer.exe -> pwsh.exe -> conhost.exe

The console window is actually hosted by WindowsTerminal.exe.

  • But if you launch WT.EXE, then a pwsh profile the process tree looks like this:
explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe
                                                                           |-> pwsh.exe

... and each additional PowerShell tab launches a new pair of OpenConsole.exe, pwsh.exe.
So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app. But I found a terrible (but working) hack:
function Get-ConsoleHostProcessId {

# Save Original ConsoleHost title	
$oldTitle=$host.ui.RawUI.WindowTitle; 
# Set unique console title.
$r=(New-Guid); 
$host.ui.RawUI.WindowTitle = "$r"; 
#Find console window by title, then find console PID.
$result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID:*" -Raw

if ($null -ne $result) {
    $consolePid = [int]($result.SubString(5).Trim());
} else {
    $consolePid = 0;
}        
# Restore original ConsoleHost title.
$host.ui.RawUI.WindowTitle=$oldTitle;

return [int]$consolePid;

}

function Test-IsWindowsTerminal {
$consolePid = Get-ConsoleHostProcessId;
if ($consolePid -gt 0) {
return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal";
}
return $false;
}

Works in pwsh. error in powershell.

Select-String : A parameter cannot be found that matches parameter
name 'Raw'.
At C:\Users\Hill\Desktop\x.ps1:9 char:97
+ ...  LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID
:*" -Raw
+
    ~~~~
    + CategoryInfo          : InvalidArgument: (:) [Select-String]
   , ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.Pow
   erShell.Commands.SelectStringCommand

change
$result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:" -Raw
to
$result = ((tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:
").toString()

@MamiyaOtaru commented on GitHub (Nov 18, 2024): > > Checking the parent process **doesn't work if WT is the Default Terminal Application**, and you launch a console app from a graphical UI app. > > > > * For example via Explorer, `Win+R` then `pwsh` (with WT as default terminal app) the process tree looks like. > > > > ``` > > svchost.exe -> WindowsTerminal.exe > > svchost.exe -> OpenConsole.exe > > > > explorer.exe -> pwsh.exe -> conhost.exe > > ``` > > > > > > > > > > > > > > > > > > > > > > > > The console window is actually hosted by `WindowsTerminal.exe`. > > > > * But if you launch `WT.EXE`, then a `pwsh` profile the process tree looks like this: > > > > ``` > > explorer.exe -> wt.exe (shim that dies immediately) -> WindowsTerminal.exe +-> OpenConsole.exe > > |-> pwsh.exe > > ``` > > > > > > > > > > > > > > > > > > > > > > > > ... and each additional PowerShell tab launches a new pair of `OpenConsole.exe`, `pwsh.exe`. > > So, for the first case, I really couldn't find a perfect solution to get the exact WindowsTerminal.exe app. But I found a terrible (but working) hack: > > function Get-ConsoleHostProcessId { > > > > # Save Original ConsoleHost title > > $oldTitle=$host.ui.RawUI.WindowTitle; > > # Set unique console title. > > $r=(New-Guid); > > $host.ui.RawUI.WindowTitle = "$r"; > > #Find console window by title, then find console PID. > > $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:*" -Raw > > > > if ($null -ne $result) { > > $consolePid = [int]($result.SubString(5).Trim()); > > } else { > > $consolePid = 0; > > } > > # Restore original ConsoleHost title. > > $host.ui.RawUI.WindowTitle=$oldTitle; > > > > return [int]$consolePid; > > } > > > > function Test-IsWindowsTerminal { > > $consolePid = Get-ConsoleHostProcessId; > > if ($consolePid -gt 0) { > > return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal"; > > } > > return $false; > > } > > Works in pwsh. error in powershell. > > ``` > Select-String : A parameter cannot be found that matches parameter > name 'Raw'. > At C:\Users\Hill\Desktop\x.ps1:9 char:97 > + ... LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID > :*" -Raw > + > ~~~~ > + CategoryInfo : InvalidArgument: (:) [Select-String] > , ParameterBindingException > + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.Pow > erShell.Commands.SelectStringCommand > ``` change $result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:*" -Raw to $result = ((tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern "PID:*").toString()
Author
Owner

@AVOnMe commented on GitHub (Jan 8, 2025):

By January 2025 we do it this way, the window doesn’t get focus so you can’t know its title.
But you count how many instances there are

Pwsh version:


$i=(Get-CimInstance Win32_Process -Filter "Name = 'OpenConsole.exe'"|select Name).Count

if ($i -le 1) {


$host.UI.RawUI.WindowTitle = "devEnv"


} else {

$drive="G:"; $host.UI.RawUI.WindowTitle = "devEnvWS"


}

Cmd batch version

for /f "tokens=* USEBACKQ" %%i in (`powershell -c "Get-CimInstance Win32_Process -Filter \"Name ^= 'OpenConsole.exe'\"|select Name" ^| find "OpenConsole.exe" /c`) do (
if %%i leq 1 (TITLE devEnv) else (
(SET "drive=G:") &TITLE devEnvWS
)
)

now that wmic is gone

then you can use one window to work on different projects

The lesson we learned is always the same, we study your behavior and then we play everything in the hand.

@AVOnMe commented on GitHub (Jan 8, 2025): By January 2025 we do it this way, the window doesn’t get focus so you can’t know its title. But you count how many instances there are **Pwsh version:** ``` $i=(Get-CimInstance Win32_Process -Filter "Name = 'OpenConsole.exe'"|select Name).Count if ($i -le 1) { $host.UI.RawUI.WindowTitle = "devEnv" } else { $drive="G:"; $host.UI.RawUI.WindowTitle = "devEnvWS" } ``` **Cmd batch version** ``` for /f "tokens=* USEBACKQ" %%i in (`powershell -c "Get-CimInstance Win32_Process -Filter \"Name ^= 'OpenConsole.exe'\"|select Name" ^| find "OpenConsole.exe" /c`) do ( if %%i leq 1 (TITLE devEnv) else ( (SET "drive=G:") &TITLE devEnvWS ) ) ``` now that wmic is gone then you can use one window to work on different projects ### The lesson we learned is always the same, we study your behavior and then we play everything in the hand.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#7868