- 2014-6-26
- Visual C++
サービスからメッセージボックスを表示する要件が出てきたので、
ちょっと調べてみた。
通常のメッセージボックスだと、色々と困った事になるので、
下記の関数を使用する。
※なぜ困った事になるかは、やったらわかる。
BOOL WTSSendMessage(
HANDLE hServer,
DWORD SessionId,
LPTSTR pTitle,
DWORD TitleLength,
LPTSTR pMessage,
DWORD MessageLength,
DWORD Style,
DWORD Timeout,
DWORD *pResponse,
BOOL bWait
);
この関数は、別のPCだったりの指定ユーザへメッセージボックスを
表示したい場合に使用するんでけども、今回は、同一PC上の指定ユーザへの表示で行う。
ちなみに、別PCの場合は、WTSOpenServer を使用して、ハンドル取得後に行います。
別PCには、同一ユーザで且つ、同一パスワードを設定していないとできないっぽい。
この辺は、別途調査しようかなと。
関数の詳細は、MSDNを参照してもらうとして、
ここの記事でも書いたサンプルを少しいじって作成。
「Windowsサービスから現在のログオンユーザを取得する」
サンプルここから
#include "wtsapi32.h" #pragma comment(lib, "wtsapi32.lib") { PWTS_SESSION_INFOW pStSesInf = NULL; DWORD dwCount = 0; DWORD dwSesId = 0; DWORD dwSize = 0; LPTSTR lpNameTmp = NULL; // ログオンユーザのセッションリストを取得する if( ::WTSEnumerateSessionsW( NULL, 0, // 予約(必ず0を指定) 1, // 列挙要求のバージョン(必ず1を指定) &pStSesInf, // 構造体の配列へのポインタを受取る &dwCount ) == FALSE ) // 構造体の数格納用(セッションリスト数) { // 取得失敗 return; } for( DWORD dwLoop = 0; dwLoop < dwCount; dwLoop++ ) { // セッションリストから順次セッション情報を取得する if( ::WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, // ターミナルサーバハンドル pStSesInf[ dwLoop ].SessionId, // セッションの識別子 WTSUserName, // セッションに関連付けられたユーザー受取を指定 &lpNameTmp, // ユーザ名ポインタ格納用 &dwSize ) == TRUE ) // 受取のデータサイズ { // 現在アクティブなセッションのIDを取得 dwSesId = ::WTSGetActiveConsoleSessionId(); // セッションIDを比較しアクティブなセッションIDと同一ならユーザ名を表示する if( pStSesInf[ dwLoop ].SessionId == dwSesId ) { CString strName; strName.Format( "\nLogonUser:%s\n", lpNameTmp ); // --------------------------- この辺から今回 ----------------------------------- // メッセージ出力対象ユーザか? if( CString( lpNameTmp ).MakeUpper() == _T( "CPNAME" ) ) { DWORD deRet = 0; TCHAR szTi[] = _T("WTSSendMessage" ); TCHAR szMs[] = _T("メッセージ 5秒後 自動消滅" ); ::WTSSendMessage( WTS_CURRENT_SERVER_HANDLE, dwSesId, szTi, sizeof( szTi ), szMs, sizeof( szMs ), MB_OK, 5, &deRet, TRUE ); // メッセージの戻り値判定 if( deRet == IDOK ) { // メッセージボックスでOKが押下された場合。 } else if( deRet == IDTIMEOUT ) { // 設定時間を経過しタイムアウトとなった場合。 } else { } } break; // --------------------------- ここまで ----------------------------------- } else { // たぶん複数ユーザでログインしている場合でアクティブじゃないユーザが表示される? // 未確認・・確認した誰か教えて・・ CString strName; strName.Format( "\nLogonUser:%s\n", lpNameTmp ); // デバック出力 TRACE( strName ); } } else { // 取得失敗 return; } } if( lpNameTmp != NULL ) { // 解放 WTSFreeMemory( lpNameTmp ); lpNameTmp = NULL; } if( pStSesInf != NULL ) { // 解放 WTSFreeMemory( pStSesInf ); pStSesInf = NULL; } }
うんな感じ。いつものように、自己責任で。。