WTSRegisterSessionNotification doesn't work so

2019-05-24 13:10发布

I'm using the function/message to check if the workstation is locked. Now my application is in the startup folder. It has worked without any problems on XP pro, but since I'm using the program on XP home WTSRegisterSessionNotification fails about 50% of the time on startup, but it never fails when the system is already booted up. Any idea why this could happen?

2条回答
放我归山
2楼-- · 2019-05-24 13:38

On XP, services start in the background and do not block boot or logon. The termsrv service is most likely not running by the time you call WTSRegisterSessionNotification.

You can check if the service is running by:

// 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);
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-05-24 13:48

Reading from the MSDN remarks section for WTSRegisterSessionNotification it says

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.

So a neat solution might be to use OpenEvent to obtain a handle to the Global\TermSrvReadyEvent event then use WaitForSingleObject (with the handle obtained from OpenEvent and a sensible timeout) to wait for the terminal services to start (causing the handle to be signalled) before calling WTSRegisterSessionNotification.

Of course, you could probably also call WTSRegisterSessionNotification to begin with then, if it fails, use GetLastError to see if it returned RPC_S_INVALID_BINDING and if so, do the above.

查看更多
登录 后发表回答