愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

WindowsのGUIアプリケーションを外部 (Linuxホスト) から実行したいんだ。どうしてもだ。

なんでそんなことをしたくなったのかは、聞かない約束だ。

しかるべきポートを開いておけば、リモートから何らかのコマンドを叩くこと自体は簡単にできる。WinRMを使ってもいいし、それこそsshdを入れてもいい。

しかしそれ系のリモートコマンドだと、GUIアプリケーションを実行することは出来ない。これは考えてみればあたり前で、GUIアプリケーションを動かせるようなセッション(ローカルでのログインなり、リモートデスクトップでのログインなり)とリモートコマンド用のセッションは分かれている。ここではセッションという言葉を適当に使っているけど気にしない。

発想を変えて、リモートからコマンドを送らずにサービス経由で特定の時間にGUIアプリケーションを起動しよう!と思ったところでこれはうまくいかない。最近のWindowsではサービスからGUIアプリを立ち上げることはできない。これをSession 0 Isolationとかいうらしい。

Application Compatibility: Session 0 Isolation

タスクスケジューラから実行する場合でも、やっぱり何らかのログインセッションがない状態で突然GUIアプリを立ち上げたりすることはできない。

ここに、PsExecというツールがある。

blog.treedown.net

これを使えば、特定のログインセッションにひも付けた形でアプリを起動できる。(沢山のポートを開放しなくちゃいけないのが残念だけど...)

つまり、「何らかのログインセッションを常時張っておくことを許容する」ならば、PsExec経由でGUIアプリを叩けるということだ。この場合のログインセッションは別にリモートデスクトップ接続でも構わないので、単につなぎっぱにしておけばよい。

セッションのIDはcmd.exeから

query session

で取れる。

残念ながらPsExecはWindowsでしか動かないツールなので、Linuxでは使えない。実はwinexeというそれっぽいツールがあるのだが、

orebibou.com

これにはPsExecのようにセッションIDを指定するような機能はない。つまり、例によってリモートからWindowsコマンドを叩けるだけのツールなのだ。が、しかし。

操作されるWindowsの方にPsExecのバイナリを置いておけば、それをwinexeから叩くこと自体は可能だ。つまり、winexe経由でPsExecを叩くことによりLinuxホストからWindowsのGUIアプリケーションを立ち上げることができる。もちろん、何らかのログインセッションを事前に張っておくこと前提で。

winexe -U "{username}%{password}" //{windows_ip_address} 'C:\PsExec \\localhost -u {username} -p "{password}" -i {session_id} notepad'

やった!notepadが起動した!

よかったですね。