You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Terminal设为默认终端时,如何用PowerShell隐藏控制台窗口?

背景

  • 需求:在PowerShell脚本中隐藏控制台窗口
    • 补充:开发一款常驻系统托盘、隐藏任务栏的截图脚本,该脚本依赖OneDrive存储截图,启动时需先完成OneDrive认证,因此初始阶段不能使用-WindowStyle Hidden参数(需显示认证窗口),认证完成后需要隐藏终端窗口并显示系统托盘图标。
  • 环境适配:当Windows 11默认终端设为Windows Console Host时,可通过以下代码隐藏窗口:
$windowcode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$asyncwindow = Add-Type -MemberDefinition $windowcode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
  $hidden = $asyncwindow::ShowWindowAsync($hwnd, 0)
}

问题

当Windows 11默认终端设为Windows Terminal时,上述代码无法获取控制台窗口句柄。改用以下代码获取句柄后,ShowWindowAsync($hwnd, 0)仅会将Windows Terminal窗口最小化,而非完全隐藏:

Add-Type -Name ConsoleAPI -Namespace Win32Util -MemberDefinition '[DllImport("Kernel32.dll")] public static extern IntPtr GetConsoleWindow();'
$hwnd = [Win32Util.ConsoleAPI]::GetConsoleWindow()
$hidden = $asyncwindow::ShowWindowAsync($hwnd, 0)

解决方案

针对Windows Terminal作为默认终端的场景,可通过以下方法实现窗口隐藏:

方法1:使用同步ShowWindow函数替代ShowWindowAsync

ShowWindowAsync在Windows Terminal环境下行为受限,改用同步的ShowWindow函数,明确传入SW_HIDE(值为0)参数:

# 定义Win32 API函数
Add-Type -MemberDefinition @'
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
'@ -Name Win32WindowUtils -Namespace Win32 -PassThru

# 获取控制台窗口句柄并隐藏
$hwnd = [Win32.Win32WindowUtils]::GetConsoleWindow()
if ($hwnd -ne [System.IntPtr]::Zero) {
    [Win32.Win32WindowUtils]::ShowWindow($hwnd, 0) # 0对应SW_HIDE常量
}

方法2:通过窗口类名+标题匹配隐藏

如果方法1无效,可以通过Windows Terminal的专属类名结合窗口标题查找目标窗口:

Add-Type -MemberDefinition @'
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
'@ -Name Win32FindWindow -Namespace Win32 -PassThru

# 获取当前PowerShell会话的窗口标题
$windowTitle = (Get-Host).UI.RawUI.WindowTitle
# 匹配Windows Terminal的窗口类名与标题并隐藏
$hwnd = [Win32.Win32FindWindow]::FindWindow("CASCADIA_HOSTING_WINDOW_CLASS", $windowTitle)
if ($hwnd -ne [System.IntPtr]::Zero) {
    [Win32.Win32FindWindow]::ShowWindow($hwnd, 0)
}

方法3:认证完成后切换到无窗口进程

若需要彻底脱离终端环境,可在认证完成后通过VBScript启动无窗口的PowerShell进程,再退出当前终端:

  1. 编写VBScript脚本(例如命名为HiddenLaunch.vbs):
Set objShell = CreateObject("WScript.Shell")
objShell.Run "powershell.exe -WindowStyle Hidden -File ""你的脚本完整路径.ps1""", 0, False
  1. 在主脚本的认证完成逻辑后添加:
# 启动无窗口进程并退出当前终端
Start-Process "wscript.exe" -ArgumentList "HiddenLaunch.vbs"
Exit

内容的提问来源于stack exchange,提问作者SATO Yusuke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:56:06