Interaction with UI from windows service
Interaction with UI from windows service
Introduction
Windows service has no UI and it has never been easy to
prompt users with some notifications from windows service.
To
interact with UI from windows service, we used to opt, allow service to
interact with desktop and by launching another process from the windows service.
But it is not expected to work with windows vista and upwards.
So
now the question is how to implement this in newer versions of windows i.e.
windows 8, windows 10 etc.
Here
is the answer:
Display
a dialog box in the user's session using the WTSSendMessage function.
It
can be used to display messages from windows service on all supported windows
operating systems.
WTSSendMessage
Displays a message box on the client desktop of a specified
Remote Desktop Services session.
Syntax
BOOL WTSSendMessageA(
IN HANDLE hServer,
IN DWORD SessionId,
LPSTR pTitle,
IN DWORD TitleLength,
LPSTR pMessage,
IN DWORD MessageLength,
IN DWORD Style,
IN DWORD Timeout,
DWORD *pResponse,
IN BOOL bWait
);
Parameters
HServer
A handle to an RD Session Host server. Specify a handle
opened by the WTSOpenServer function, or specifyWTS_CURRENT_SERVER_HANDLE to
indicate the RD Session Host server on which your application is running.
SessionId
A Remote Desktop Services session identifier. To indicate
the current session, specify WTS_CURRENT_SESSION. You can use
the WTSEnumerateSessions function to retrieve
the identifiers of all sessions on a specified RD Session Host server.
pTitle
A pointer to a null-terminated string for the title bar of
the message box.
TitleLength
The length, in bytes, of the title bar string.
pMessage
A pointer to a null-terminated string that contains the
message to display.
MessageLength
The length, in bytes, of the message string.
Style
The contents and behavior of the message box. This value is
typically MB_OK. For a complete list of values, see the uType parameter
of the MessageBox function.
Timeout
The time, in seconds, that the WTSSendMessage function
waits for the user's response. If the user does not respond within the time-out
interval, the pResponse parameter returns IDTIMEOUT.
If the Timeout parameter is zero, WTSSendMessage waits
indefinitely for the user to respond.
pResponse
A pointer to a variable that receives the user's response.
Code
class NotifyService
{
[DllImport("wtsapi32.dll", SetLastError
= true)]
static extern bool WTSSendMessage(
IntPtr hServer,
[MarshalAs(UnmanagedType.I4)] int SessionId,
String pTitle,
[MarshalAs(UnmanagedType.U4)] int TitleLength,
String pMessage,
[MarshalAs(UnmanagedType.U4)] int MessageLength,
[MarshalAs(UnmanagedType.U4)] int Style,
[MarshalAs(UnmanagedType.U4)] int Timeout,
[MarshalAs(UnmanagedType.U4)] out int pResponse,
bool bWait);
public static IntPtr
WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
//public static
int WTS_CURRENT_SESSION = 1;
public void Start(int lastRebootDaysDiff)
{
try
{
bool result = false;
String title = "Support";
int tlen = title.Length;
// lastRebootDaysDiff = 0;
if (lastRebootDaysDiff >= 0)
{
string msg = lastRebootDaysDiff +
"days have passed since you have rebooted your machine.
Would you like to reboot your system now?";
int mlen = msg.Length;
int resp = 7;
//result = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, user_session,
title, tlen, msg, mlen, 4,
// 0, out resp, true);
result =
WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, 1, title, tlen, msg, mlen, 4,
0, out resp, false);
int err = Marshal.GetLastWin32Error();
if (err == 0)
{
if (result) //user responded to box
{
if (resp == 7) //user clicked no
{
}
else if (resp == 6) //user clicked yes
{
// write your functionality here
}
//
Debug.WriteLine("user_session:" + user_session + "
err:" + err + " resp:" + resp);
}
}
}
}
catch (Exception ex)
{
// Debug.WriteLine("no
such thread exists", ex);
}
}
}
Comments
Post a Comment