別ソフトを開くようなコマンドを実行したあと、(特に最大化せずに複数ウィンドウを並べながら作業しているようなとき)開いていたターミナル画面が邪魔になることがないでしょうか?
そんなときは下記の内容を $PROFILE
から読み込んでおくと、処理の最後に Hide-ConsoleWindow
と呼び出すことでターミナル画面を最小化することができます。
function Get-ConsoleWindowHandle {
$p = Get-Process -Id $PID
$i = 0
while ($p.MainWindowHandle -eq 0) {
if ($i++ -gt 10) {
return $null
}
$p = $p.Parent
}
return $p.MainWindowHandle
}
$Global:CONSOLE_HWND = Get-ConsoleWindowHandle
if(-not ('Console.Window' -as [type])) {
Add-Type -Name Window -Namespace Console -MemberDefinition `
@'
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
public static void Minimize(IntPtr hwnd) {
SendMessage(hwnd, 0x0112, 0xF020, 0);
}
'@
}
function Hide-ConsoleWindow {
if ($Global:CONSOLE_HWND -and ($env:TERM_PROGRAM -ne "vscode")) {
[Console.Window]::Minimize($Global:CONSOLE_HWND)
}
}
仕組みとしては C# のコードを Add-Type してウィンドウを操作しています。
(ドキュメント を見たところ、 Add-Type はデフォルトで名前空間 System
を参照し、さらに -MemberDefinition
を指定すると自動的に System.Runtime.InteropServices
も参照するようです。ヒアドキュメント内のインデントが浅くなりコード内への埋め込みやすさが上がりますね)
ウインドウハンドル取得のためにわざわざ Get-ConsoleWindowHandle
を作っているのは Cmder や ConEmu などのコンソールエミュレータを想定しています。1回ではウィンドウハンドルを取得できないことがあるため、最大10回のリミットを設けてループさせています。
何もしないと VSCode の統合ターミナル上で実行したときに VSCode 自体が最小化されてしまうので、前回の記事 でも紹介した $env:TERM_PROGRAM
で判定しています。