Following is the sample C++ code for using WTSSendMessage from a task running in non-interactive session 0.
Although the logged-on user's interactive session id will usually be 1 this is not guaranteed to always be the case. So the sample uses the WTSEnumerateSessions function to obtain the session id for the active session. The session id is one of the parameters passed to WTSSendMessage.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WtsApi32.h>
#pragma comment(lib, "wtsapi32")
#include <stdio.h>
#include <tchar.h>
void Report(LPCTSTR pszFormat, ...)
{
TCHAR szMsg[512];
va_list pArg;
va_start(pArg, pszFormat);
_vsntprintf_s(szMsg, ARRAYSIZE(szMsg), ARRAYSIZE(szMsg) - 1, pszFormat, pArg);
va_end(pArg);
OutputDebugString(szMsg);
}
int _tmain()
{
TCHAR szTitle[]{ _T("Information") };
TCHAR szMsg[]{ _T("Hello From TaskMessageBox") };
DWORD dwResp{};
PWTS_SESSION_INFO pwsi{};
DWORD dwSession{}, dwCount{};
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, &pwsi, &dwCount))
{
Report(_T("WTSEnumerateSessions failed with error code %d\n"), GetLastError());
return 0;
}
for (DWORD i = 0; i < dwCount; i++)
{
if (pwsi[i].State == WTSActive)
{
dwSession = pwsi[i].SessionId;
break;
}
}
WTSFreeMemory(pwsi);
if (!dwSession)
{
Report(_T("No active sessions\n"));
return 0;
}
BOOL fSuccess = WTSSendMessage(WTS_CURRENT_SERVER, dwSession, szTitle, ARRAYSIZE(szTitle) * sizeof(TCHAR),
szMsg, ARRAYSIZE(szMsg) * sizeof(TCHAR), MB_ICONINFORMATION | MB_OK, 60, &dwResp, TRUE);
if (fSuccess)
Report(_T("WTSSendMessage succeeded, response was %d\n"), dwResp);
else
Report(_T("WTSSendMessage failed, error code was %d\n"), GetLastError());
return 0;
}