使用.NET Windows服务在Windows 7中显示消息框

3

如何在Windows 7中使用.NET Windows服务显示消息框

我们有一个Windows服务,用于在Windows XP上用户扫描其访问卡后显示确认消息框,但一旦我们迁移到Windows 7,该弹出功能就不再起作用。如此帖子所述Displaying Message Box using .NET Windows Services In Windows 7,我按照说明操作,当我将应用程序运行为控制台应用程序时,它可以正常工作,但是当我将其安装为Windows服务时,它无法工作。以下是我的代码。同时,result变量返回false,err变量返回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();

}
2个回答

2
WTSSendMessage() 的调用指定了 WTS_CURRENT_SESSION,这意味着“在当前会话上显示消息框”。当您作为服务运行时,您在会话 0 上,这是Windows 7 上的隔离会话。您肯定不希望您的消息框出现在那里!
要在常规用户会话中显示,您必须提供非零会话 ID。有关详细信息,请参阅WTSSendMessage() 文档

2
您声明了WTSGetActiveConsoleSessionId,但是从未调用它。该函数返回当前活动的会话ID。这就是您必须传递给WTSSendMessage的会话ID。
您当前的代码试图在服务的会话0中显示消息,而不是您想要的会话。
在调用该函数之前,您必须更正其声明。您拼写错误了,它的名称是WTSGetActiveConsoleSessionId。
我认为字符串长度参数需要考虑零终止符。将传递的值加1。如果您切换到Unicode API,则必须将这些值乘以2,因为它们是以字节而不是字符来衡量的。
还有一点。只有在API调用失败时才询问错误代码。因此,在您的代码中,只有在结果为false时才调用Marshal.GetLastWin32Error。

我尝试使用WTSGetActiveConsoleSessionID(),但由于某些原因它会导致Windows服务崩溃。我做错了什么吗? - Baahubali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接