OpenSSH経由のリモートログインでもGUIアプリケーションを起動する仕組みを作る
本連載でこれまでに説明したように、OpenSSH経由でWindowsにリモートログインした場合、そこからはGUIアプリケーションを起動できない。しかし、Windows上の仮想環境やWSL2で動作しているUbuntuから、Windows側のGUIアプリケーションを起動したいケースはある。やはり、OpenSSH経由でリモートログインしている状態でもGUIアプリケーションを起動したいのだ。
こうしたことから、本連載ではGUIアプリケーションが起動できる状態のサーバを起動しておいて、そのサーバにアプリケーションの実行を依頼するかたちでこれを実現する方法を紹介した。作成したのは、次のPowerShellスクリプト「wincmdserver.ps1」だ。
#!/usr/bin/env pwsh
#========================================================================
# 特定のファイルに書き込まれたコマンドを実行する簡易サーバ
#========================================================================
#========================================================================
# コマンドが書き込まれるファイル
#========================================================================
$commandFilePath = "${HOME}/.wincmdserver_cmd"
#========================================================================
# ファイルをチェックするインターバル時間[秒]
#========================================================================
$fileCheckInterval = 1.0
#========================================================================
# コマンドが書き込まれるファイルを初期化
#========================================================================
Write-Output $null > $commandFilePath
#========================================================================
# コマンドが書き込まれるファイルを監視して、コマンドが書き込まれた場合には
# コマンドを実行してファイルをクリアする
#========================================================================
while ($true) {
# コマンドファイルが存在し、かつ、中身があるときに中身を実行する
if (Test-Path "$commandFilePath") {
if (0 -lt (Get-ChildItem "$commandFilePath").Length) {
# ファイルに書き込まれたコマンドを実行
Invoke-Expression (cat "$commandFilePath")
# ログ出力
$timestamp = Get-Date -format "yyyy/MM/dd HH:mm:ss"
$timestamp + " - " + (cat "$commandFilePath")
# ファイルの中身をクリア
Clear-Content "$commandFilePath"
}
}
# 次のチェックまで指定秒間待機
Start-Sleep $fileCheckInterval
}
このPowerShellスクリプトを実行しておけば、${HOME}/.wincmdserver_cmdに書き込まれた文字列がコマンドとして実行されるようになる。要するに特定のファイルにGUIアプリケーションを起動するコマンドを書き込めば、それが実行されるという仕組みである。
タスクスケジューラに登録する
「この機能は常に動作していてほしい」「使うときに都度起動するのは面倒だ」「常に背後で動いていてほしい」――これを実現するものとして、前回「タスクスケジューラ」を取り上げた。説明の中で、簡単なPowerShellスクリプトをタスクスケジューラに登録し、Windowsにログオンしたら自動的に実行されるところまでを確認した。この機能をwincmdserver.ps1に適用してみよう。
タスクスケジューラを起動して、新しいタスクを作成する。重要な部分のスクリーンショットだけ、以下に掲載しておく。
操作(アクション)としてここでは次の内容を登録している。「引数の追加」や「開始」に登録するパスについては、状況に応じて書き換えていただきたい。
項目 | 内容 |
---|---|
操作 | プログラムの開始 |
プログラム/スクリプト | "C:\Program Files\PowerShell\7\pwsh.exe" |
引数の追加 | Command "C:\Users\daichi\wincmdserver.ps1" |
開始 | C:\Users\daichi |
この状態でシステムを再起動、または、いったんログアウトしてからログオンする。すると次のように、登録したPowerShellスクリプトが起動する。以前はこのターミナルウインドウを表示しないオプションが機能していたのだが、現在は使用できなくなっている。とりあえず動作はするので、今はこのままにしておこう。邪魔になったらウインドウを最小化すればよい。
動作確認
では、動作を確認してみよう。WSL2で動作しているLinuxでもよいし、ほかのホストからでもよいので、WindowsへOpenSSH経由でリモートログインして、${HOME}/.wincmdserver_cmdファイルへコマンドを書き込む。次のようなイメージだ。
ほかのホストから実行するコマンドの例
ssh ホスト 'echo "コマンド" > $HOME/.wincmdserver_cmd'
Windows側では次のように${HOME}/.wincmdserver_cmdファイルへ書き込んだコマンドが実行され、アプリケーションが起動する。
このように、Windowsにログオンした状態でOpenSSH経由でのGUIアプリケーションが起動できる状態になっていることを確認できる。
これまで示してきたように、リモートログインからGUIアプリケーションを起動するために特別なことはしていない。必要なPowerShellスクリプトを作成し、それをタスクスケジューラに登録してログオン時に自動的に起動するようにしただけだ。それでも、これだけ実用的な機能を実現できる。ユーザーによっては、さまざまな操作を自動化できるとても重要な機能となるだろう。あるとないとでは、大きな違いになるはずだ。