June 18th, 2026
likeintriguing2 reactions

Why doesn’t Get­Last­Input­Info() return info for the user I’m impersonating?

A customer had a Windows NT service process, and from that service process, they wanted to obtain the last input time for all signed-in users. Their strategy was to use WTS­Query­User­Token() to get the token for each user, use that token to impersonate the user, and then call Get­Last­Input­Info() to get the last input time for that user. Unfortunately, the function always return the last input info for the service session, and since services are not interactive, it always says that there has been no input since the system booted.

Does Get­Last­Input­Info() work with impersonation?

Recall that the default answer to “Does this work when impersonating?” is “No”. And in fact, the documentation for Get­Last­Input­Info() explicitly says that it doesn’t, if you read it closely.

This function is useful for input idle detection. However, GetLastInputInfo does not provide system-wide user input information across all running sessions. Rather, GetLastInputInfo provides session-specific user input information for only the session that invoked the function.

I underlined the important part. It reports on the last input information for the session that invoked the function. When the service impersonates, it updates its security context to align with that of the user being impersonated, but it doesn’t change the fact that that it is still running in session zero, the service session.

If you need to get last input information from another session, you will need a friend in that session to call it for you. Typically this is done by launching a helper process into the target session: The helper process collects the information you want and then sends the information to the service.

Bonus chatter: A related question is “Does Get­Async­Key­State from a service?” The answer is technically yes, it works. However it probably doesn’t work the way you think. It returns the asynchronous key state for the desktop that the service is running in. And since services run in a non-interactive session, that desktop will never see any keyboard activity.

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

5 comments

Sort by :
  • Joshua Hudson 1 day ago

    Related: suppose I *am* on the user’s desktop (my current method; as a service, locate the active desktop, find the associated winlogon process, and steal its token). Does it work despite the fact I’m not the user. (The means by which this is performed seems to preclude continuing to impersonate the user, but really doesn’t. It’s just a royal pain to continue to impersonate the user from here.)

    If the answer is yes, then this is a solution to the problem if the API must be called. However, the real question ought to be “how did you get here?”.

  • Paul Jackson 3 days ago

    “It returns the asynchronous key state for the desktop that the service is running in. And since services run in a non-interactive session, that desktop will never see any keyboard activity.”

    What about keyboard activity in the UNC dialog?

    • Me Gusta

      A service cannot interact with other logon sessions directly. They are always stuck in session 0 and other users log into session 1 onwards. This has how it has been since Windows Vista. What's more, because of fast user switching, it wasn't even recommended to create an interactive service even in Windows XP.

      But anyway, when you ask "What about XXX?" think about what you know of services.

      Does the service directly create the window? If it does, then it is a dialog in session 0 and so all logged on users will be unable to view it. In this situation, the...

      Read more
  • Baltasar García 4 days ago · Edited

    I don’t want to be a nitpicker, I was honestly confused. I guess that the first sentence of the last paragraph (Bonus Chatter), should be:

    > A related question is “Does `Get­Async­Key­State` **work** from a service?”

  • Henke37 4 days ago

    A quick way to answer these types of questions would be: What about terminal services?