问题
Displaying Message Box using .NET Windows Services In Windows 7
We had a windows service that was used to display a confirmation message box once a user scanned their access card on windows xp but once we migrated to windows 7, that pop up functionality no longer works. As described in this post Displaying Message Box using .NET Windows Services In Windows 7 , i have followed the instruction and it works when i run the application as console application but when i install it as a windows service it does not work. below is my code. Also the result variable is returning false and the err variable is returning 5.
class Class1
{
public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
public static int WTS_CURRENT_SESSION = -1;
public void test()
{
bool result = false;
string title = "Hello";
int tlen = title.Length;
string msg = "Terminal Service!";
int mlen = msg.Length;
int resp = 0;
result = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, title, tlen, msg, mlen, 0, 0, out resp, true);
int err = Marshal.GetLastWin32Error();
System.Console.WriteLine("result:{0}, errorCode:{1}, response:{2}", result, err, resp);
}
[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);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern int WTSGetActiveConsoleSessionID();
}
回答1:
You've declared WTSGetActiveConsoleSessionId but then never called it. That function returns the session ID that is currently active. That's the session ID that you must pass to WTSSendMessage.
Your current code is attempting to display the message in the service's session, session 0. Not what you intended.
Before you can call the function though, you must correct its declaration. You have spelled it incorrectly. It is named WTSGetActiveConsoleSessionId.
I believe that the string length parameters need to account for the zero terminator. Add 1 to the values that you pass. If you switched to the Unicode API then you'd have to multiply these values by 2 since they are measured in bytes rather than characters.
One more point. Only ever ask for the error code when the API call fails. So in your code you must only call Marshal.GetLastWin32Error if result is false.
回答2:
The call to WTSSendMessage() specifies WTS_CURRENT_SESSION, which means "show the message box on the current session". When you run as a service, you are on session 0, which is isolated on Windows 7. You surely don't want your message box to show up there!
To show up on a regular user's session, you have to provide a non-zero session ID. See the WTSSendMessage() documentation for details.
来源:https://stackoverflow.com/questions/18732110/displaying-message-box-using-net-windows-services-in-windows-7