I want to hide the console window in a PowerShell script.
-WindowStyle Hidden
option (the window for authentication should be shown). After authentication, I want to hide the terminal from the taskbar and show the system tray icon.On Windows 11, when you set Windows Console Host
as the "Default terminal application" in the Startup setting of Windows Terminal, you can hide the console windows like this:
$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)
}
On Windows 11, when you set Windows Terminal
as the "Default terminal application" in the Startup setting of Windows Terminal, you can't get the window handle of console windows with the code above.
Instead of the code above, you can get the window handle like this:
Add-Type -Name ConsoleAPI -Namespace Win32Util -MemberDefinition '[DllImport("Kernel32.dll")] public static extern IntPtr GetConsoleWindow();'
$hwnd = [Win32Util.ConsoleAPI]::GetConsoleWindow()
$hidden = $asyncwindow::ShowWindowAsync($hwnd, 0)
But in this code, ShowWindowAsync($hwnd, 0)
doesn't work properly. According to the document of ShowWindowAsync, it hides the windows when you pass 0 as the 2nd parameter. When I ran the code above, the Windows Terminal window is minimized rather than hidden.
How can I hide the console window with PowerShell when you set Windows Terminal
as the "Default terminal application" in the Startup setting of Windows Terminal on Windows 11?
Based on @postanote and @Luuk's answers, I made a function to hide the console window like this:
function Hide-ConsoleWindow() {
$ShowWindowAsyncCode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$ShowWindowAsync = Add-Type -MemberDefinition $ShowWindowAsyncCode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
# When you got HWND of the console window:
# (It would appear that Windows Console Host is the default terminal application)
$ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
# When you failed to get HWND of the console window:
# (It would appear that Windows Terminal is the default terminal application)
# Mark the current console window with a unique string.
$UniqueWindowTitle = New-Guid
$Host.UI.RawUI.WindowTitle = $UniqueWindowTitle
$StringBuilder = New-Object System.Text.StringBuilder 1024
# Search the process that has the window title generated above.
$TerminalProcess = (Get-Process | Where-Object { $_.MainWindowTitle -eq $UniqueWindowTitle })
# Get the window handle of the terminal process.
# Note that GetConsoleWindow() in Win32 API returns the HWND of
# powershell.exe itself rather than the terminal process.
# When you call ShowWindowAsync(HWND, 0) with the HWND from GetConsoleWindow(),
# the Windows Terminal window will be just minimized rather than hidden.
$hwnd = $TerminalProcess.MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
$ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
Write-Host "Failed to hide the console window."
}
}
}