问题
Visual C++ 2008
How to establish whether or not the currently interactive user is at either the Locked desktop (Windows-Key L) or the Shutdown Screen (Vista or 7) waiting for programs to close during log-out.
HDESK hd = OpenInputDesktop(0, false, READ_CONTROL);
This works fine for a user app on the Default desktop, but fails with error Code 5 when at the Locked or Shutdown desktops due to, I understand, the user not having permissions to open the secure desktop object.
Calling this from a Service running under the SYSTEM account returns error 1 (invalid function). I believe that the Service is in any case in the wrong session (Session 0) and is unable to determine the interactive desktop for any other session.
I have an app running under the currently interactive user, and also, the system service running, so could do the code from either.
Should I perhaps attempt to enumerate all of the sessions, Window stations and desktops?
Even then how do I determine the currently interactive desktop if I can only make the call to OpenInputDesktop from the SYSTEM service in session 0?
回答1:
I think you can try these methods:
-
From a process running in currently interactive user:
UseWTSRegisterSessionNotificationto register for session change notifications. Once registered, interactive process would get logon/logoff notifications. More info can be found here:
http://msdn.microsoft.com/en-us/library/aa383841.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2006/01/04/509194.aspx -
From a service (running in session 0):
- Use
GetProcessWindowStationto get the current station handle of service, and save it for later use. - Use
WTSGetActiveConsoleSessionIdto get session id of current interactive session. - Get station name corresponding to current session id using
WTSQuerySessionInformationwithWTSWinStationNameinfo class. - Open this station using
OpenWindowStation. Set this station to your service process usingSetProcessWindowStation. - Now, you can use
OpenInputDesktopto check if user has logged-in or not. - Close the opened interactive window station by calling
CloseWindowStation. Reset the original window station of service by callingSetProcessWindowStationwith station handle saved earlier.
- Use
PS: Currently, "WinSta0" is the only interactive station in Windows. So, you can skip WTSGetActiveConsoleSessionId and WTSQuerySessionInformation calls.
回答2:
Beware:
MSDN about WTSQuerySessionInformation with WTSWinStationName:
Note: Despite its name, specifying this type does not return the window station name. Rather, it returns the name of the Remote Desktop Services session. Each Remote Desktop Services session is associated with an interactive window station. Currently, since the only supported window station name for an interactive window station is "WinSta0", each session is associated with its own "WinSta0" window station. For more information, see Window Stations.
来源:https://stackoverflow.com/questions/4260878/openinputdesktop-to-determine-secure-login-desktop