2014年12月19日金曜日

Windows Vista/7以降のリモートセッション

Windows でのリモートセッションについて、つい最近まで誤解をしていた。

ここでリモートセッションとは、クライアントがリモートデスクトップでサーバにログインしているセッションで、クライアント側にセッションのデスクトップが表示される、ことを指す。

Windows 2000/XP/2003 ではアプリケーションで GetSystemMetrics に SM_REMOTESESSION 引数を与えて呼び出すと、アプリケーションが実行されているセッションがリモートセッションであると判断して構わなかった。同じように Vista以降の OS でも SM_REMOTESESSION でリモートセッションかどうかを判断して構わないと思っていたが、これは誤った認識だった。

Vista以降のWindowsを対象にしたプログラムで SM_REMOTESESSION を使ってリモートセッションであるかどうかを判断するコードを追加したのだが、しばらくはその部分は呼び出されなかった。その後、その部分を利用するようになってから、プログラムが訳の分からない動作をするようになった。原因は、ローカルセッション(コンソールに接続されているセッション)にも関わらず、SM_REMOTESESSION はリモートセッションであると判断していたことだった。WebでSM_REMOTESESSIONを検索すると、色々なページで SM_REMOTESESSIONを使って判断できるようなことが書いてある。以前にも、SM_REMOTESESSIONが返す値がおかしいと疑ったが、Web検索では、問題があるようなことはどこにも見つからなかった。そのため、SM_REMOTESESSIONを使ったコードを残したままだったことが、長い間問題の種になってしまったようだ。

リモートデスクトップ経由でリモートのクライアントに表示されているセッションであるかどうかは、WTSQuerySessionInformation API の WTS_INFO_CLASS引数に WTSClientProtocoleType を指定して呼び出して判断す方法が正しい結果になるようだ。 ユーザ切り替えを標準でサポートし始めた Vista以降では、セッションの情報は、セッション自身に問い合わせるのがベストプラクティスだと思う。