关于 winapi:WTSRegisterSessionNotification 在 XP 主页启动时有时不起作用

WTSRegisterSessionNotification doesn't work sometimes on startup with XP home

我正在使用该功能/消息来检查工作站是否被锁定。现在我的应用程序位于启动文件夹中。它在 XP pro 上运行没有任何问题,但由于我在 XP home 上使用该程序 WTSRegisterSessionNotification 在启动时大约有 50% 的时间失败,但在系统已经启动时它永远不会失败。知道为什么会发生这种情况吗?


从 WTSRegisterSessionNotification 的 MSDN 备注部分中读取它说

If this function is called before the dependent services of Terminal Services have started, an RPC_S_INVALID_BINDING error code may be returned. When the Global\\TermSrvReadyEvent global event is set, all dependent services have started and this function can be successfully called.

所以一个巧妙的解决方案可能是使用 OpenEvent 获取 Global\\TermSrvReadyEvent 事件的句柄,然后使用 WaitForSingleObject(使用从 OpenEvent 获取的句柄和合理的超时)等待终端服务启动(导致在调用 WTSRegisterSessionNotification 之前要发出信号的句柄)。

当然,你也可以先调用WTSRegisterSessionNotification,如果失败,使用GetLastError查看是否返回RPC_S_INVALID_BINDING,如果返回,执行上述操作。


在 XP 上,服务在后台启动,不会阻止启动或登录。在您调用 WTSRegisterSessionNotification 时,termsrv 服务很可能没有运行。

您可以通过以下方式检查服务是否正在运行:

1
2
3
4
5
6
7
8
9
10
11
// Error handling omitted for brevity
SC_HANDLE scm = OpenSCManager(NULL, NULL, GENERIC_READ);
SC_HANDLE svc = OpenService(scm, L"TermSrv", SERVICE_QUERY_STATUS);
SERVICE_STATUS status;
QueryServiceStatus(svc, &status);
if (status.dwCurrentSTate != SERVICE_RUNNING) {
    // Try to start, wait and try again, etc.
}

CloseServiceHandle(svc);
CloseServiceHandle(scm);