Windows Vista以降、コンソールセッションとサービスセッションは分離されてしまいました。
セッション 0 の分離 - Windows 7 対応アプリケーションの互換性
Windows Vista® および Windows Server® 2008 アプリケーション互換性解説書
私もそうだったのですが、Vista以前のOSで「セッションIDが0だったら、コンソールセッション」という判定しているコードだとはまってしまうことになります。リモート管理接続ではローカルと同じ、リモートデスクトップ機能ではリモート専用のコードという動きになってほしい場合、どうしても判定する必要があります。いや、普通に作ってたら大丈夫だろうという突込みはなしで…。
そこで改めて調べてみたのですが、リモートかローカルか判定する方法は三通り用意されています。あ、WMI経由で取得する方法もあるかもしれませんね。
GetSystemMetricsを使う
GetSystemMetrics function (Windows)int iMetricsResult = GetSystemMetrics(SM_REMOTESESSION);
Windows 3.1時代からある伝統の関数。Windows Server 2003の管理コンソールに接続した状態ではこの関数は正しく「リモートではない」と判定します。
GetVersionEx
次はちょっと新しめのOS(Windows 2000以降かな)でしか使えない、GetVersionEx()。GetVersionEx function (Windows)
構造体のwSuiteMaskにVER_SUITE_TERMINALが有効で、VER_SUITE_SINGLEUSERTSが無効であれば複数人が同時でアクセスしているアプリケーションサーバーモード(つまり管理接続ではない)であるということになります。
OSVERSIONINFOEX osex; ZeroMemory(&osex, sizeof(OSVERSIONINFOEX)); osex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); BOOL bVerify = GetVersionEx((LPOSVERSIONINFO)&osex);
WTSQuerySessionInformationを使う
Windows Server 2008 R2以降の方法。ただし、これ私の手元では動きませんでした。WTSQuerySessionInformation function (Windows)
WTSQuerySessionInformationの新しい値WTSIsRemoteSessionを使います。なぜかWINVERに0x600を定義しなくても使えてしまうのですが。
TRUEを返却するとリモートセッションであるそうなのですが、管理接続ではFALSEでした。手元にRDS-CALを入れた環境を持っていないので、だれか試してくれるとうれしいなぁ(^^;。
BOOL bIsRemote = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSIsRemoteSession, NULL, NULL);