- 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;
}
}
うんな感じ。いつものように、自己責任で。。







