TL;DR
PowerShellスクリプトを経由してtopコマンド自作っぽい事をする。
一度設定すると、以下の操作で下記画像のような自作topを実行できるようになる。
Win+R -> "top"と入力 -> Enterキー
下記スクリプトを作成し、ユーザーディレクトリ(例: C:\Users\[username]\)内で「右クリック → 新規作成 → ショートカット」でショートカットを作成。
項目の場所:powershell -ExecutionPolicy RemoteSigned -File "%USERPROFILE%\top.ps1"
ショートカットの名前:top
$SAMPLE_INTERVAL = 1.0
$INTERVAL_STEP = 0.5
$PROCESS_DISPLAY_LIMIT = 20
$NAME_MAX_LENGTH = 20
$interval = 2
function Show-ProcessData {
param([psobject]$data, [double]$interval)
Clear-Host
Write-Host ("Interval: {0,4:0.0}s | [UP/DN] +/- 0.5s | [1-9] Set seconds" -f $interval) -ForegroundColor Green
Write-Host ""
Write-Host ("{0,-20} {1,10}" -f "ProcessName", "CPU(%)")
Write-Host ("-" * 31)
$data.CounterSamples |
Where-Object { $_.Status -eq 0 -and $_.InstanceName -notmatch "^(_total|idle|system)$" } |
Sort-Object CookedValue -Descending |
Select-Object -First $PROCESS_DISPLAY_LIMIT |
ForEach-Object {
$pName = if ($_.InstanceName.Length -gt $NAME_MAX_LENGTH) {
$_.InstanceName.Substring(0, $NAME_MAX_LENGTH - 3) + "..."
} else {
$_.InstanceName
}
Write-Host ("{0,-20} {1,10:N1}" -f $pName, [Math]::Round($_.CookedValue, 1))
}
Write-Host "`n[Ctrl+C] to Stop" -ForegroundColor Gray
}
function Get-NextUpdateTime {
param([double]$interval)
[DateTime]::Now.AddSeconds([Math]::Max(0.0, $interval - $SAMPLE_INTERVAL))
}
function Update-Display {
param([psobject]$data, [double]$interval)
if ($data) {
Show-ProcessData $data $interval
}
Get-NextUpdateTime $interval
}
$nextUpdateTime = Get-NextUpdateTime $interval
$data = $null
# Initial display
Clear-Host
Write-Host "Loading process data..." -ForegroundColor Yellow
# Main loop
while($true) {
# Get key input without blocking
if ([Console]::KeyAvailable) {
$key = [Console]::ReadKey($true)
switch ($key.Key) {
'UpArrow' { $interval += $INTERVAL_STEP }
'DownArrow' { $interval = [Math]::Max(1.0, $interval - $INTERVAL_STEP) }
default {
if ($key.KeyChar -match '[1-9]') {
$interval = [int]([string]$key.KeyChar)
}
}
}
$nextUpdateTime = Update-Display $data $interval
}
# Update display
if ([DateTime]::Now -ge $nextUpdateTime) {
# Previous data display if error occurs
try {
$data = Get-Counter -Counter "\Process(*)\% Processor Time" -SampleInterval $SAMPLE_INTERVAL -MaxSamples 1 -ErrorAction Stop
} catch {}
$nextUpdateTime = Update-Display $data $interval
}
# Reduce CPU usage
Start-Sleep -Milliseconds 100
}
作った理由
最近マルチコア化が進んできてCPUが16とか32個の論路コアのマシンで、1,2コアをフルに使った場合とか、タスクマネージャーでは、実際にCPUをどれくらい食っているかほとんど分からない (Solarisモード表示)。
Linuxのtopコマンドなら、コアごとの負荷が分かる (Irixモード表示)。
なので、Windowsにも欲しい、Windowsにtopコマンドを実装する方法は無いか、と思った。
- Solarisモードは、CPUの全コアをフルに使った場合に
100%と表示される。論理コア10個で2スレッド無限ループなら20% - Irixモードは、コア数に関係なく、1スレッドをフルに使っていれば
100%と表示される。2スレッドフルなら200%
たぶん今回のやり方なら、スタート(Winキー) -> "top" (検索窓に記入) でも出るかも。
cmd(コマンド プロンプト)から呼ぶには.\top.lnk、PowerShellから呼ぶには./top等(cmdと同じ表記でも可)のようです。
あらゆる場面でもtopで呼びたい方は、エイリアスを作るなどAIに訊いて頑張ってください・・・。
ショートカットについては、PowerShellスクリプトの実行制限かかっているマシンでも実行時のみ許可するよう、実行時ポリシーにRemoteSignedを一時的に設定しています。PC自体の設定は変更されません。
