0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VirtualDesktopのVRアプリを終了させた時、SteamVRも終了させたい

Posted at

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 "監視スクリプトを終了します。"

コード解説

  1. 監視対象プロセスの設定
    $processName に対象とするVRアプリのプロセス名(例: DepthVideoPlayerVR.exe)を設定します。

  2. WMIクエリの定義
    クエリ内で TargetInstance.Name を指定して、対象プロセスの終了イベントのみを監視するようにしています。

  3. イベント登録とアクション
    Register-WmiEvent でイベントを登録し、対象プロセスが終了したときにアクションブロック内で以下を実行します。

    • 終了したプロセス名とPIDを表示
    • Start-Process を利用して、cmd.exe 経由で taskkill /IM vrmonitor.exe /f を実行し、SteamVRのプロセスを終了
    • グローバル変数 $global:donetrue に設定し、メインの監視ループを終了させる
  4. 監視ループ
    while ループで $global:donetrue になるまで待機し、監視を継続します。

実行方法

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にお願いして記事書いてもらいました)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?