最可靠的检测方式是检查 WT_SESSION 环境变量是否存在:PowerShell 中用 $env:WT_SESSION 判断是否为空,CMD 中用 if defined WT_SESSION,Bash 中用 [ -n "$WT_SESSION" ];该变量由 Windows Terminal 注入,普通 PowerShell 或 conhost 中不存在,且微软官方承诺其稳定性与兼容性。

检查 WT_SESSION 环境变量是否存在
Windows Terminal 会为每个启动的进程注入 WT_SESSION 环境变量,其值为一个 UUID 字符串。这是最直接、最可靠的检测方式,且 PowerShell、CMD、WSL 子系统等只要在 Windows Terminal 中运行,都会携带该变量。
- 在 PowerShell 中:用
$env:WT_SESSION判断是否为空 - 在 CMD 中:用
if defined WT_SESSION echo in WT - 在 Bash(如 WSL)中:用
[ -n "$WT_SESSION" ] && echo "in WT" - 注意:
WT_SESSION在普通 PowerShell(即 pwsh.exe 或 powershell.exe 启动的独立窗口)中一定不存在,所以这个判断不会误报
区分 Windows Terminal 和原生 PowerShell 控制台
仅靠 $PSVersionTable.PSEdition 或 $host.Name 无法区分——因为 PowerShell 可以在 Windows Terminal、Console Host(conhost.exe)、Windows Terminal Preview、甚至 VS Code 终端里运行。关键不是“是不是 PowerShell”,而是“当前宿主终端是不是 Windows Terminal”。
-
$host.Name在 Windows Terminal 中仍是ConsoleHost,和 conhost 一致,不可靠 -
$env:TERM在 Windows Terminal 的 PowerShell/WLS 中常为xterm-256color,但 CMD 下为空,且 VS Code 终端也设这个值,不能单独依赖 - 真正有效的组合判断是:
($env:WT_SESSION) -and ($env:WT_PROFILE_ID)(后者标识当前配置文件 ID,进一步确认非伪造)
PowerShell 启动时自动适配终端环境
如果你在 $PROFILE 中需要根据终端类型加载不同配置(比如在 Windows Terminal 中启用真彩色,而在 conhost 中禁用),建议用以下模式:
if ($env:WT_SESSION) {
$IsWindowsTerminal = $true
# 启用 ANSI 转义序列支持(Windows 10 1607+ 默认已开,但保险起见)
if ($PSVersionTable.PSVersion.Major -ge 5) {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
}
}
else {
$IsWindowsTerminal = $false
# 可选:降级颜色方案或禁用某些 VT 特性
}- 不要依赖
$env:PROCESSOR_ARCHITECTURE或$IsWindows—— 它们只说明系统平台,不反映终端类型 - 避免用窗口标题(
$host.UI.RawUI.WindowTitle)匹配,容易被用户修改或受编码影响 -
WT_SESSION是微软官方文档明确承诺的稳定标识,未来兼容性有保障
为什么不用 Get-Process 查父进程?
有人尝试通过 Get-CimInstance Win32_Process -Filter "ProcessId = $($PID)" 回溯父进程名来判断,这条路问题很多:
- PowerShell Core(pwsh)可能由
explorer.exe直接启动,跳过终端进程 - WSL 启动的 PowerShell 会显示
init或bash为父进程,完全丢失终端上下文 - VS Code 终端、JetBrains IDE 内置终端也会注入自己的进程链,干扰判断
- 权限限制下,
Get-CimInstance可能失败,而环境变量始终可读
环境变量方案简单、稳定、无权限依赖,是唯一推荐路径。复杂终端嵌套场景下,别试图“猜”进程树——WT_SESSION 就是为此而生的。










