VirtualDesktopでVRアプリを利用していると、アプリが終了したタイミングでSteamVRのプロセスも自動で終了させたいというニーズがあります。(主に右手コントローラだけで操作できるがメニューボタンが無くてVRを終了できない時など!)
今回は、PowerShellとWMIイベントを使って、特定のプロセス(ここではVRアプリ)終了時にSteamVRのプロセス(vrmonitor.exe)を終了する方法を紹介します。
背景
OpenXR対応のVRアプリで緊急終了した場合、SteamVRがそのまま動作し続けるとデスクトップに戻れず困りますね。ボスが間もなくドアを開けるというのに!
そこで、対象のVRアプリが終了したことを検知して、SteamVRに関連するプロセスを自動終了させる仕組みを構築します。
実現方法
PowerShellのWMIイベント(__InstanceDeletionEvent)を利用すると、プロセスの終了(オブジェクトの削除)イベントを監視できます。
監視対象のプロセスが終了した際に、指定したアクションを実行するように設定します。
サンプルコード
以下は、監視対象のプロセス名を DepthVideoPlayerVR.exe
とし、そのプロセスが終了したら SteamVR のプロセス vrmonitor.exe
を taskkill コマンドで終了する例です。
# monitor.ps1
$processName = 'DepthVideoPlayerVR.exe'
$global:done = $false
# 対象プロセスのみを監視するクエリ
$query = "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = '$processName'"
Register-WmiEvent -Query $query -Action {
$proc = $Event.SourceEventArgs.NewEvent.TargetInstance
Write-Host "終了したプロセス: $($proc.Name) (PID: $($proc.ProcessId))"
# SteamVRのプロセス(ここでは vrmonitor.exe )を終了させる
Start-Process -FilePath "C:\Windows\System32\cmd.exe" -ArgumentList "/C", "taskkill /IM vrmonitor.exe /f"
# グローバルフラグを設定してメインループで終了を検知
$global:done = $true
} | Out-Null
Write-Host "プロセス終了の監視を開始しています。"
# 監視ループ。対象プロセスが終了すると、グローバルフラグでループ終了
while (-not $global:done) {
Start-Sleep -Seconds 1
}
Write-Host "監視スクリプトを終了します。"
コード解説
-
監視対象プロセスの設定
$processName
に対象とするVRアプリのプロセス名(例: DepthVideoPlayerVR.exe)を設定します。 -
WMIクエリの定義
クエリ内でTargetInstance.Name
を指定して、対象プロセスの終了イベントのみを監視するようにしています。 -
イベント登録とアクション
Register-WmiEvent
でイベントを登録し、対象プロセスが終了したときにアクションブロック内で以下を実行します。- 終了したプロセス名とPIDを表示
-
Start-Process
を利用して、cmd.exe 経由でtaskkill /IM vrmonitor.exe /f
を実行し、SteamVRのプロセスを終了 - グローバル変数
$global:done
をtrue
に設定し、メインの監視ループを終了させる
-
監視ループ
while
ループで$global:done
がtrue
になるまで待機し、監視を継続します。
実行方法
VRアプリの起動と同時にこの監視スクリプトを非表示モードで実行する場合は、以下のようなバッチファイルを用いると便利です。
@echo off
rem VRアプリ(DepthVideoPlayerVR.exe)を起動
start "" "C:\Path\to\DepthVideoPlayerVR.exe"
rem 監視用の PowerShell スクリプトを非表示で起動
start "" powershell.exe -WindowStyle Hidden -NoProfile -File "%~dp0monitor.ps1"
このバッチファイルを実行すると、VRアプリと監視スクリプトが同時に起動し、VRアプリが終了した際に SteamVR のプロセスも自動的に終了します。
注意点
-
WMIイベントの動作:
WMIイベントは別の実行コンテキストで動作するため、イベント内のexit
ではなくグローバル変数を使ってメインループを制御しています。 -
プロセス名の一致:
対象プロセス名は正確に記述する必要があります。実際の環境に合わせて適宜変更してください。 -
管理者権限:
一部のプロセスの監視や終了には管理者権限が必要となる場合があります。必要に応じて管理者権限で実行してください。
まとめ
PowerShellとWMIイベントを活用することで、特定のVRアプリが終了した際に自動でSteamVRのプロセスも終了させる仕組みを構築できます。
今回のサンプルでは、DepthVideoPlayerVR.exeの終了を検知して、vrmonitor.exe(SteamVR関連プロセス)を taskkill コマンドで終了させる例を紹介しました。
この仕組みを利用して、サボりVRをより安全かつスマートに実現してください!
(※大体LLMにお願いして記事書いてもらいました)