ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

Windows XPの簡易ユーザ切り替え機能

Windows XPからログインを維持したまま複数のユーザの切り替えができる機能が搭載された。
今更感があるけどサンプル等も少ないので載せてみることにする。


基本的な流れとしては、
1、WTSRegisterSessionNotification()で切り替え時にウィンドウメッセージを送信するように登録する。
2、ユーザの切り替え時にWM_WTSSESSION_CHANGEが発行されるので切り替え処理を行う。
3、使用終了の際はWTSUnRegisterSessionNotification()で登録の解除を行う。


これらの関数群は wtsapi32.h と wtsapi32.lib で宣言、定義されている。
また、使用の際は _WIN32_WINNT が 0x0501 以上であること


以降、"ユーザの切り替え"を"セッションの切り替え"と記述する


1の手順でセッションの切り替えが検知できるようになると、2のWM_WTSSESSION_CHANGEが発行される。


このときの wParam には、セッションの切り替え通知が送信された理由を示す状態コードが含まれ、lParam には WTSSESSION_NOTIFICATION構造体へのポインタが含まれ、対象となるセッションIDが格納される。


wParam の状態コードを下記に示す。

意味
WTS_CONSOLE_CONNECT コンソールセッションが接続された
WTS_CONSOLE_DISCONNECT コンソールセッションが切断された
WTS_REMOTE_CONNECT リモートセッションが接続された
WTS_REMOTE_DISCONNECT リモートセッションが切断された
WTS_SESSION_LOGON ユーザがログオンした
WTS_SESSION_LOGOFF ユーザがログオフした
WTS_SESSION_LOCK セッションがロックされた
WTS_SESSION_UNLOCK セッションがアンロックされた
WTS_SESSION_REMOTE_CONTROL リモート制御状態のセッションが変更された


lParam の構造体はこのように宣言されている。

typedef struct tagWTSSESSION_NOTIFICATION{
    DWORD cbSize;
    DWORD dwSessionId;
} WTSSESSION_NOTIFICATION, *PWTSSESSION_NOTIFICATION;

実際にセッションの切り替えが発生したときには WTS_SESSION_LOCK が発行されるが、これはセッションの切り替え画面が表示されている場合のみロックされるようで、実際に自分が制御権を握っているのは WTS_CONSOLE_CONNECT から WTS_CONSOLE_DISCONNECT の間のようである。
よって、セッションが切り替えられた場合には WTS_CONSOLE_DISCONNECT を捕まえ、セッションが復帰した場合には WTS_CONSOLE_CONNECT を捕まえればよいらしい。


ちなみに、セッションの切り替え機能はWnidows XP以降でしか使用できない機能なので、Windows 2000で実行すると WTSRegisterSessionNotification() などが定義されておらず、実行時エラーとなってしまうので注意。
Windows XPWindows 2000の両方で使用する可能性がある場合にはDLLから直接ロードしたほうが無難と思われる。


また、この関数は接頭辞 WTS にもなっている "Windows Terminal Services" を使用しているため、"Terminal Services"というサービスが起動しないと使用できないようである(結合ハンドルが無効です。といったエラーが出る)。
このため、スタートアップ等でアプリケーションを起動する場合は、"Terminal Services"の起動を待つ処理が必要になる。


最後にセッションの切り替えは複数のユーザをまたぐためデバッグが非常にやっかい。
一番早いのがシリアルで別PCにTRACEする方法と思う。


サンプルプログラムはまた明日。


参考サイト

  1. [http://support.microsoft.com/kb/310153/ja:title=[HOW TO] Windows XP でユーザーの簡易切り替えをサポートするアプリケーションの作成方法]
  2. WinXP の簡易ユーザー切り替えを検知する
  3. セッションの切り替えを自分のアプリケーションで検出する