c# - .NET Windows 服务 (WTSSendMessage) : Displays message on XP but not Windows 7

标签 c# windows

我在 Windows 7 上使用 .NET 窗口服务显示消息时遇到问题。它在 Windows XP 上正常工作。我知道它在 Windows 7 上不起作用,如 Microsoft 网站和一些论坛(包括 Stackoverflow)中所述。我按照 Stackoverflow 中提到的来自 Pinvoke.NET 的以下示例(使用 WTSSendMessage)进行了操作。但它也没有工作。该示例在 Windows XP 上正常工作。有人可以帮助我吗,因为这是一个非常大的问题需要尽快修复,因为我们已经迁移到 Windows7。

签名:

[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;

代码:

  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, false);
    int err = Marshal.GetLastWin32Error();
    System.Console.WriteLine("result:{0}, errorCode:{1}, response:{2}", result, err, resp);

最佳答案

WTS_CURRENT_SESSION 用于 Windows 7 或更高版本上的服务将等同于 session 0,不允许用户交互。您必须枚举所有事件 session 并向每个 session 发送一条消息(应该只是一个,除非计算机正在运行终端服务)。类似于以下内容:

签名:

    [DllImport("wtsapi32.dll", SetLastError = true)]
    static extern int WTSEnumerateSessions(
                    System.IntPtr hServer,
                    int Reserved,
                    int Version,
                    ref System.IntPtr ppSessionInfo,
                    ref int pCount);

    public enum WTS_CONNECTSTATE_CLASS
    {
        WTSActive,
        WTSConnected,
        WTSConnectQuery,
        WTSShadow,
        WTSDisconnected,
        WTSIdle,
        WTSListen,
        WTSReset,
        WTSDown,
        WTSInit
    }

辅助函数:

public static List<Int32> GetActiveSessions(System.IntPtr server)
{
    List<Int32> ret = new List<int>();
    IntPtr ppSessionInfo = IntPtr.Zero;

    Int32 count = 0;
    Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
    Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));

    Int64 current = (int)ppSessionInfo;

    if (retval != 0)
    {
        for (int i = 0; i < count; i++)
        {
            WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
            current += dataSize;

            if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive)
                ret.Add(si.SessionID);
        }

        WTSFreeMemory(ppSessionInfo);
    }

    return ret;
}

在您的代码中:

    List<Int32> sessions = GetActiveSessions(WTS_CURRENT_SERVER_HANDLE);
    if (sessions.Count < 1)
    {
        int err = Marshal.GetLastWin32Error();
        _SUDSEventLog.WriteEntry("No active sessions found: errorCode:", err);
    }
    else
    {
        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, sessions[0], title, tlen,
        msg, mlen, 0, 0, out resp, false);
        int err = Marshal.GetLastWin32Error();
        System.Console.WriteLine("result:{0}, errorCode:{1}, response:{2}", result, err, resp);
    }

关于c# - .NET Windows 服务 (WTSSendMessage) : Displays message on XP but not Windows 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18731740/

相关文章:

c# - 您如何通过添加数字来创建唯一的文件名?

c# - core 2.0 和 office interop - microsoft.office.core 包在哪里?

windows - 命令提示随机数是如何生成的?

c# - Azure api 请求被中止 : Could not create SSL/TLS secure channel. http 客户端在调用某些 Web api 时

c# - 热带矩阵乘法

c# - 引用类型存在于堆中,值类型存在于栈中

java - 如何以编程方式从另一个程序中关闭在 Windows 中运行的特定 Java 应用程序?

python - 如何在 Windows 上使用 cython 编译 __init__.py 文件

windows - 在 MSYS 中获取挂载目录的真实 Windows 目录(或将 ln 与 MSYS 一起使用)

windows - 如何在本地 Kubernetes 上运行 Windows 容器?